gpt4 book ai didi

C++ AVL 树迭代器不会正确递增

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:33:04 25 4
gpt4 key购买 nike

我在我的 AvlTree 类中实现了一个类迭代器。我的AvlTree节点如下:

    struct AvlNode
{
Comparable element;
list<int> lines; //line occurrences
bool flag; //checks validity
AvlNode *left;
AvlNode *right;
AvlNode *parent; //parent pointer
int height;

AvlNode( const Comparable & theElement, AvlNode *lt, AvlNode *rt, AvlNode *pt,
int h = 0, bool b = true )
: element( theElement ), left( lt ), right( rt ), parent( pt ), height( h ), flag( b ) { }
};

我的迭代器如下:

     class iterator
{
protected:

friend class AvlTree<Comparable>;
AvlNode * node;

AvlNode * findInOrderSuccessor(AvlNode * & t)
{
AvlNode * temp;
//node has a right child
// so successor is leftmost node of right subtree
if(t->right != NULL)
{
temp = t->right; //go right
//go all the way left
while(temp->left != NULL)
{
temp = temp->left;
}
return temp;
}

//node has no right child
//if we are someone's left child, go up one
if(t->parent->left == t)
{
//return your parent
temp = t->parent;
return temp;
}
//if we are someone's right child, go up until the current node
//is someone's left child, then go up one more
temp = t->parent;
while(temp->parent->left != temp)
{
temp = temp->parent; //go up
}
//return your parent
temp = t->parent;
return temp;

}

public:
iterator(AvlNode * p) : node(p)
{ }

//overload * to make *iterator return the element of its node
Comparable & operator*()
{ return node->element; }

iterator operator++ (int) //postfix operator
{
node = findInOrderSuccessor(node);
return iterator(node);
}

// == comparison overload
bool operator==(iterator rhs)
{ return node == rhs.node; }
// != comparison overload
bool operator!=(iterator rhs)
{ return !(*this == rhs); }
};

我的 AvlTree 也有一个开始和结束迭代器作为公共(public)成员:

    //begin iterator points to leftmost node
iterator begin()
{ //return pointer to leftmost node
AvlNode *temp = root;
while(temp->left != NULL)
temp = temp->left;
return iterator(temp);
}

//end iterator points to one after rightmost node
iterator end()
{ //return NULL right pointer of rightmost node
AvlNode * temp = root;
while(temp->right != NULL)
temp = temp->right;
return iterator( temp->right );
}

我的问题是,当我尝试在 main 中运行以下命令时:

    for(AvlTree<string>::iterator itr = tree.begin(); itr != (tree.end()); itr++)
cout << *itr << endl;

我没有按顺序输出字符串树中的所有单词,而是得到树中第一个有序项的无限循环。我似乎无法弄清楚为什么它不会超过第一项。

最佳答案

以下迭代代码有效(来自 my AVL tree ;用 leftright 代替 link[0]link[ 1]):

BAVLNode * BAVL_GetFirst (const BAVL *o)
{
if (!o->root) {
return NULL;
}

BAVLNode *n = o->root;
while (n->link[0]) {
n = n->link[0];
}

return n;
}

BAVLNode * BAVL_GetNext (const BAVL *o, BAVLNode *n)
{
if (n->link[1]) {
n = n->link[1];
while (n->link[0]) {
n = n->link[0];
}
} else {
while (n->parent && n == n->parent->link[1]) {
n = n->parent;
}
n = n->parent;
}

return n;
}

就您的代码而言,首先,end() 不需要找到最右边的节点才能返回iterator(NULL);它可以在不查看树的情况下直接返回。

然而,您的算法中的实际错误似乎在这里:

        temp = t->parent;
WRONG: while(temp->parent->left != temp)
{
temp = temp->parent; //go up
}
//return your parent
WRONG: temp = t->parent;
return temp;

}

我标记的第一行可能会尝试取消引用 NULL 指针,应更改为:

while(temp->parent && temp->parent->left != temp)

第二个:

temp = temp->parent;

此外,您可能已经从我的代码中注意到以下内容现在是多余的;它可以被删除,并且将由(固定的)剩余代码以完全相同的方式处理。它还遭受我在上面指出的相同的 NULL 指针取消引用。

//if we are someone's left child, go up one
if(t->parent->left == t)
{
//return your parent
temp = t->parent;
return temp;
}

关于C++ AVL 树迭代器不会正确递增,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9597817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com