AVL TREE in c++
I have a problem with this very simple block of code. please give me your advice . (My this problem is solved, and in solving this problem the person having id stakx really helped me, the only problem was that i was using stack< treeNode >, when i saw the push method of the stack carefully, there is a copying process when i write head->object=number, so finally i made the stack of pointers, like this stack< treeNode* > and it really solved the problem , i have no problem now , i am very very thankful to the person stakx.)
before the code you need to suppse the following tree
alt text http://img44.imageshack.us/img44/7016/avlimage06.jpg as you can see in the picture that root is 8 and stack have two nodes i.e 6 and 4. i pass this stack and root node to the following codevoid Avltree::attachwithtree(treeNode* tree, Stack<treeNode>&s)
{
if(!s.isempty())
{
tr开发者_开发问答eeNode *stacknode;
stacknode=s.pop();
cout<<"\ninside the attachwithtree function, stack node is "<<stacknode->data;
stacknode->right=tree;//attaching the passed node to the right of popped node
root=stacknode;//setting the root to stack node which is the private data member of class
updatebalance(root);//this function is ok, it does not create problem
while(!s.isempty())
{
cout<<"\nstack is still not empty";
stacknode=s.pop();
cout<<"\nright side of "<<root->data<<" is "<<(root->right)->data;
//the below three lines causing the problem i don't know why,
root=stacknode;
treeNode* temp;
temp=root->right;
cout<<"\n\n\nthe right side of "<<temp->data<<" is now "<<(temp->right)->data;
updatebalance(root);
}
the ouptput of this function is given by
here is the code of the pop method of the stack that i am using
template <class t>
t * Stack<t>::pop()
{
if(topelement!=NULL)
{
t* num;
current=topelement;
num=&(current->object);
topelement=topelement->preptr;
current=topelement;
return(num);
}
else
{
head=NULL;
}
}
here is the code of push method of the stack
template <class t>
void Stack<t>::push(t &number)
{
Node<t>* newNode=new Node<t>;
if(head==NULL)
{
head=newNode;
topelement=newNode;
current=newNode;
head->object=number;
head->preptr=NULL;
}
else
{
topelement=newNode;
newNode->preptr=current;
current=topelement;
newNode->object=number;
}
}
Original answer:
Could it be that the node 4
on the stack has a different node 6
to its right (the one with node 7
to its right) than the node 6
(with the node 8
on its right) you're working on? You could compare their addresses to make sure you haven't got two different copies of node 6
around.
Elaboration on the above argument:
Let's look at your method's signature:
void Avltree::attachwithtree(treeNode* tree, Stack<treeNode>&s)
s
is defined as a reference to a Stack<treeNode>
.
Could it be that it should be a Stack<treeNode*>
?
Depending on your treeNode
class, it's possible that when you push X
on this stack, you actually end up with a copy of X
and not X
itself. Similarly, when you pop from the stack, you might not actually get the item you pushed, but an identical-looking copy of it!?
This would mean that, at the time when you push node 6
on the stack, its right child is node 7
. But you have pushed a new, identical node on the stack. Even if you pop this element from the stack and change it, you only change a copy and leave the original tree node as it was before.
Therefore, you'd operate on different copies of node 6
. First, you pop a copy of it from the stack, and append a tree as its right child. Checking this will give the right result.
Then, you pop a copy of node 4
from the stack. It's right child is node 6
, as expected, BUT not the one you just modified but the original! Therefore you get 7
on the right side of node 6
.
Demonstrating the difference between pass-by-value and pass-by-reference:
OK, here's something you need to understand when working with pointers or references. It basically shows the difference between passing a parameter by value (a copy will be created) or passing it by reference (no copy will be created).
Study it carefully and then see how it applies to your problem.
#include <iostream>
class someObject
{
private:
int _value;
public:
someObject(int value) : _value(value) { }
int getValue()
{
return _value;
}
};
void someFunction(someObject objCopy, someObject* objPtr)
{
std::cout << "objCopy.getValue() -> " << objCopy.getValue() << std::endl;
std::cout << "objPtr->getValue() -> " << objPtr->getValue() << std::endl;
if ( &objCopy != objPtr )
{
std::cout << "objCopy is not actually *objPtr but a copy of it." << std::endl;
}
else
{
std::cout << "objCopy and *objPtr are one and the same object." << std::endl;
}
}
int main()
{
someObject X(17);
someFunction(X, &X);
return 0;
}
Hint: Yes, in your pop
method, you work with pointers, but most likely with a pointer to a copy of the object originally pushed on the stack.
Is that your own Stack class? A quick look at the STL tells me that pop() has return type void.
It could be that stakx is onto something here. If your pop() function returns a copy of the top element rather than a reference to it, the changes you make will only apply to the copy. Do you explicitly add the copy back into the tree anywhere after modifying it?
精彩评论