写了个程序,出了问题,还以为结构体不能按引用传递。事实证明,我错了,我错误的原因也找到了,跟结构体的引用没有任何关系。罗嗦一点,把二叉树的非递归后序遍历代码和自己写的链栈GetTop函数贴在下面:
template <class ElemType> void PostOrderTraverse_I(TreeNode<ElemType>* t,void (*Visit)(ElemType& e)) { StackNode<ElemType> curnode,topnode; LinkStack<StackNode<ElemType> > S; TreeNode<ElemType>* p=t; do { while(p) { curnode.ptr=p; curnode.tag=0; S.Push(curnode); p=p->LeftChild(); } S.GetTop(topnode); while(!S.StackEmpty()&&topnode.tag==1) { S.Pop(curnode); p=curnode.ptr; Visit(p->data); S.GetTop(topnode); } if(!S.StackEmpty()) { S.GetTop(topnode); topnode.tag=1; p=topnode.ptr->RightChild(); } } while(!S.StackEmpty()); }
template <class ElemType> bool LinkStack<ElemType>::GetTop(ElemType& e) { if(top==base) { return false; } else { e=top->next->data; return true; } }
注意最下面的两行红色代码。我的本意是想修改栈顶元素topnode的tag值为1。但是单步跟踪发现执行的那两行红色代码好像没起什么作用,单从最后那个if语句中看,topnode的tag确实被赋值为1,可是,当循环再次执行到上面的红色代码GetTop时,发现topnode的tag值竟然还是0。于是我很纳闷,StackNode类型的结构体topnode明明是按照引用传递给函数GetTop的啊,为什么栈顶元素的tag竟然没有变呢···
现在想想很可笑哈,原因如下:执行S.GetTop(topnode); topnode.tag=1;之后,topnode的tag确实变了,但是请注意,真正的栈顶元素的tag并没有变啊。我们改变的topnode只不过是一个普普通通的变量,它没有在栈顶!S.GetTop(topnode);的意义只是按照栈顶元素的模样修改了一个没有位于栈中的变量topnode而已。于是,我把后序遍历的函数做了简单修改:
template <class ElemType>
void PostOrderTraverse_I(TreeNode<ElemType>* t,void (*Visit)(ElemType& e))
{
StackNode<ElemType> curnode,topnode;
LinkStack<StackNode<ElemType> > S;
TreeNode<ElemType>* p=t;
do
{
while(p)
{
curnode.ptr=p;
curnode.tag=0;
S.Push(curnode);
p=p->LeftChild();
}
S.GetTop(topnode);
while(!S.StackEmpty()&&topnode.tag==1)
{
S.Pop(curnode);
p=curnode.ptr;
Visit(p->data);
S.GetTop(topnode);
}
if(!S.StackEmpty())
{
S.Pop(topnode);
topnode.tag=1;
S.Push(topnode);
p=topnode.ptr->RightChild();
}
} while(!S.StackEmpty());
}
一个因为粗心造成的bug就这样解决了。