二元搜索树的非递归迭代器

时间:2013-10-20 21:47:16

标签: c binary-tree traversal

我有一个与此类似的main.c文件:

it = bet_create_iterator(bstree);

while ((n = bst_iter_next(it))) {
    printf("value: %d", bst_getvalue(n));
}

我希望你能从上面看到它的用途。虽然是我的问题。它的功能,

bst_iter_next(it)

它返回指向树中节点的指针。

我发现以递归方式遍历BST非常简单,但这样做,每次返回一个节点都很困难。

如果有人可以帮助一个人并向我解释如何做到这一点,我将不胜感激。

干杯,

安迪。

2 个答案:

答案 0 :(得分:0)

it成为节点双指针,并且每次调用bst_iter_next(it)时都将其指向行中的下一个节点。假设您正在post order遍历树并致电it = bet_create_iterator(bstree);。现在您的it指向根节点。接下来,您致电bst_iter_next(it);。它会做这样的事情:

bst_iter_next(node **it) {
    if (*it has children) {
       *it = *it->left;
       return *it
    }
    else if (*it->parent == NULL)
        *it = NULL or whatever;
        return NULL;
    else {
       node *n = *it;
       while(1) {
          if(n->parent == NULL) {
             *it = NULL or whatever;
             return NULL;
          }
          if(n->parent->left == n && n->parent->right!= NULL) {
              *it = n->parent->right;
              return *it;
          }
          else
              n = n->parent;
       }
    }
}

无论如何,这似乎在我的脑海中起作用,但我的逻辑可能有缺陷。

答案 1 :(得分:0)

这是我做的一种方式:

struct node{
    int value;
    struct node *left, *right, *parent;
    int visited;
};

struct node* iter_next(struct node* node){
    struct node* rightResult = NULL;

    if(node==NULL)
        return NULL;

    while(node->left && !(node->left->visited))
        node = node->left;

    if(!(node->visited))
        return node;

    //move right
    rightResult = iter_next(node->right);

    if(rightResult)
        return rightResult;

    while(node && node->visited)
        node = node->parent;

    return node;
}

技巧是为每个节点同时提供父链接和访问标记。此外,必须调用iter_next()而不改变树结构的状态(当然),而且"访问"标志不会改变值。

以下是调用iter_next()的tester函数,每次为此树打印值:

                  27
               /      \
              20      62
             /  \    /  \
            15  25  40  71
             \  /
             16 21

int main(){

    //right root subtree
    struct node node40 = {40, NULL, NULL, NULL, 0};
    struct node node71 = {71, NULL, NULL, NULL, 0};
    struct node node62 = {62, &node40, &node71, NULL, 0};

    //left root subtree
    struct node node16 = {16, NULL, NULL, NULL, 0};
    struct node node21 = {21, NULL, NULL, NULL, 0};
    struct node node15 = {15, NULL, &node16, NULL, 0};
    struct node node25 = {25, &node21, NULL, NULL, 0};
    struct node node20 = {20, &node15, &node25, NULL, 0};

    //root
    struct node node27 = {27, &node20, &node62, NULL, 0};

    //set parents
    node16.parent = &node15;
    node21.parent = &node25;
    node15.parent = &node20;
    node25.parent = &node20;
    node20.parent = &node27;
    node40.parent = &node62;
    node71.parent = &node62;
    node62.parent = &node27;

    struct node *iter_node = &node27;

    while((iter_node = iter_next(iter_node)) != NULL){
        printf("%d ", iter_node->value);
        iter_node->visited = 1;
    }
    printf("\n");
    return 1;
}

将按排序顺序打印值:

15 16 20 21 25 27 40 62 71