非递归后序遍历二叉树,请看这里。
方法一:递归调用用的是call stack,为了把递归调用转化成非递归调用,我们要想办法用普通的栈代替call stack。
教科书里的非递归前序遍历算法,需要用两个嵌套循环来做。本算法的仅仅需要一个循环就能完成前序遍历。详见preorder1()
初始化:
首先把根节点入栈。
循环以下各步,直至栈为空:
1.出栈;(出栈的时候,打印节点的值);
2.对于刚才被弹出的节点,检查是否有右孩子:有右孩子的话,先把右孩子压栈;然后检查有没有左孩子,有的话再把左孩子入栈。
3.返回到第1步。
方法二:请见preorder2()。方法二和非递归中序遍历的思路非常像。
代码如下:
#include<iostream>
#include<stack>
using namespace std;
class Node
{
public:
int key; // value of node
Node* lp; // pointer to left child
Node* rp; // pointer to right child
Node(int k, Node*lpp, Node* rpp)
{
key = k;
lp = lpp;
rp = rpp;
}
};
void preorder1(Node* root)
{
std::stack<Node*> st;
if(root!=NULL)
st.push(root);
Node* tmp;
while(!st.empty())
{
tmp = st.top();
st.pop();
cout<<tmp->key<<endl;
if(tmp->rp!=NULL)
st.push(tmp->rp);
if(tmp->lp!=NULL)
st.push(tmp->lp);
}
}
void preorder2(Node* root) //第二种方法
{
stack<Node*> st;
while(root!=NULL || !st.empty())
{
while(root)
{
printf("%d|", root->value);
st.push(root);
root = root->left;
}
if(st.empty())
break;
else
{
root = st.top();
st.pop();
root = root->right;
}
}
}
int main()
{
Node* n1 = new Node(1,NULL,NULL);
Node* n2 = new Node(2,NULL,NULL);
Node* n3 = new Node(3,n1,n2);
Node* n4 = new Node(4,NULL,NULL);
Node* n5 = new Node(5,NULL,NULL);
Node* n6 = new Node(6,n4,n5);
Node* n7 = new Node(7,n3,n6);
Node* root = new Node(8,NULL,n7);
preorder1(root);
preorder2(root);
}