这是前序遍历的迭代版本。想法是为了
将根推入堆栈。
如果左子不是NULL。推左子,root = root-> left
否则root =栈顶; Pop;推右子,root = root->右
它在一些树上工作但是对于一些输入树它会打印一个重复的值。堆栈的行为是令人惊讶的。它如何从(4 5 6 8)变为(4 6 8)?
void preorder(node* root)
{stack<node*> st;
st.push(root);
cout<<root->val<<" \n ";
while(!st.empty())
{if(root->left!=NULL)
{st.push(root->left);
cout<<st.top()->val<<" ";
// printstack(st);
root=root->left;
}
else{root=st.top();
st.pop();
if(root->right!=NULL)
{st.push(root->right);
cout<<st.top()->val<<" ";
//printstack(st);
root=root->right;
}
}
}
}
用于调试的辅助函数printstack
void printstack(stack<node*> s)
{stack<node*> t;
t=s;
while(!t.empty())
{cout<<t.top()->val<<" ";
t.pop();
}
}
对于此输入树,打印的堆栈位于下方。
预订单输出为
8 3 1 6 5 4 4 7 9
______8_ / \ __3_ 9 / \ 1 ___6 / \ 5 7 / 4
3 8
1 3 8
6 8
5 6 8
4 5 6 8
4 6 8 //堆栈顶部4怎么样?它应该是5,堆栈是(5 6 8)
7 8
9
答案 0 :(得分:0)
问题出现在已离开孩子但不对的节点上。当节点具有正确的子节点时,最后一个if块在下一次迭代之前更改根节点,但没有它,根节点不会切换。然后,下一次,我们看到一个有一个左子项的根(已经弹出堆栈),所以它的左子被推入堆栈并再次访问。
希望有所帮助。
答案 1 :(得分:0)
预订遍历
初始化: 将Root节点推送到堆栈
While(Stack not Emtpy)
{
Node = Stack.pop();
print Node;
Push Node->right onto the Stack (pushing first, as I need to process left tree first.
Stack is LIFO)
Push Node->left onto the Stack
}
上面的伪代码应该打印预订序遍历。
答案 2 :(得分:0)
这是正确的代码,它是对代码的修改。只需查看更改
void preorder(node * r1)
{stack<node*> st;
st.push(r1);
node* root;
root=r1;
cout<<root->val<<" ";
while(!st.empty())
{if(root->left!=NULL)
{st.push(root->left);
cout<<st.top()->val<<" ";
root=root->left;
}
else{root=st.top();
st.pop();
if(root->right!=NULL)
{st.push(root->right);
cout<<st.top()->val<<" ";
root=root->right;
}
else
root->left=NULL;
}
}
}