二叉树的迭代法后序、中序遍历
递归法实现二叉树的后序、中序遍历较为简单,本文将介绍模拟递归的过程,使用迭代法实现后序遍历和中序遍历的方法。
后序遍历
后序遍历的顺序为:左右中。以下面的二叉树为例,是不是可以先打印‘9’这个节点呢?显然不是,因为‘9’又是下一个子树的父节点,打印它之前必须先打印它的左节点。所以我们必须一直找到最左节点
(1)。
假设我们已经找到了最左节点,也就是‘15’,那么我们能打印吗?思考一下,我们是后序遍历,打印顺序为左右中,此时‘15’还有一个右节点‘4’,那么我们必须先打印‘15’的右节点‘4’。所以找到了最左节点后,还必须确认右边是否还有节点
(2)。
再假设一下,我们也找到了‘4’这个节点,接下来应该干什么呢?显然,应该和根节点‘3’的操作一样:先找最左边的节点,在确认有没有右子节点。因为节点‘4’现在就是所在子树的根节点(其实不能说是根节点,而是父节点)
(3)。
在上面的叙述中,我们总结了3点需要注意的(红体字部分)。接下来我们就针对以上3点,逐步写出后序遍历的迭代实现。
第一点:所以我们必须一直找到最左节点
(1)
void PostOrder(TreeNode* node)
{
stack<TreeNode*> st;
TreeNode* current = node;
if (current) st.push(current);
while (!st.empty()){
//找到最左侧的节点
while (current){
if (current->leftChild) st.push(current->leftChild); //由于还需要原路返回,所以查找过程需将节点入栈
current = current->leftChild;
}
}
}
上述代码可以让我们一直找到节点‘15’,并将‘3’,‘9’,‘15’这条路径压入栈中,以便返回时使用。
第二点:所以找到了最左节点后,还必须确认右边是否还有节点
(2)。
当退出上述的while循环时,current指针指向‘15’的左节点,也就是NULL。此时,我们需从栈中取出一个节点,用于路径返回,并且检查是否有右节点。接着上面的代码,继续写,如下:
void PostOrder(TreeNode* node)
{
stack<TreeNode*> st;
TreeNode* current = node;
if (current) st.push(current);
while (!st.empty()){
//1找到最左侧的节点
while (current){
if (current->leftChild) st.push(current->leftChild); //由于还需要原路返回,所以查找过程需将节点入栈
current = current->leftChild;
}
//2确认右边是否还有节点
current = st.top();//取出栈中的节点
/*判断是否有右节点,没有则打印当前节点*/
if (current->rightChild) {
st.push(current->rightChild);
current = current->rightChild;
}
else{
std::cout << current->data << " ";
st.p