二叉树的遍历方式分别有三种:先序,后序,中序。
而每种遍历都分别有俩种方式:递归与非递归。
递归算法很短:
先序:
void preorder(){
cout << data << " ";
if(lchild != NULL){
lchild->preorder();
}
if(rchild != NULL){
rchild->preorder();
}
}
中序:
void inorder(){
if(lchild != NULL){
lchild->inorder();
}
cout << data << " ";
if(rchild != NULL){
rchild->inorder();
}
}
后序:
void postorder(){
if(lchild != NULL){
lchild->inorder();
}
if(rchild != NULL){
rchild->inorder();
}
cout << data << " ";
}
而对于非递归算法:
如下为截至http://blog.csdn.net/ns_code/article/details/12977901/朋友的一篇引用。
1、前序遍历的非递归实现
根据先序遍历的顺序,先访问根节点,再访问左子树,后访问右子树,而对于每个子树来说,又按照同样的访问顺序进行遍历,上图的先序遍历顺序为:ABDECF。非递归的实现思路如下:
对于任一节点P,
1)输出节点P,然后将其入栈,再看P的左孩子是否为空;
2)若P的左孩子不为空,则置P的左孩子为当前节点,重复1)的操作;
3)若P的左孩子为空,则将栈顶节点出栈,但不输出,并将出栈节点的右孩子置为当前节点,看其是否为空;
4)若不为空,则循环至1)操作;
5)如果为空,则继续出栈,但不输出,同时将出栈节点的右孩子置为当前节点,看其是否为空,重复4)和5)操作;
6)直到当前节点P为NULL并且栈空,遍历结束。
具体实现:
void pre_traverse(BTree pTree)
{
PSTACK stack = create_stack(); //创建一个空栈
BTree node_pop; //用来保存出栈节点
BTree pCur = pTree; //定义用来指向当前访问的节点的指针
//直到当前节点pCur为NULL且栈空时,循环结束
while(pCur || !is_empty(stack))
{
//从根节点开始,输出当前节点,并将其入栈,
//同时置其左孩子为当前节点,直至其没有左孩子,及当前节点为NULL
printf("%c ", pCur->data);
push_stack(stack,pCur);
pCur = pCur->pLchild;
//如果当前节点pCur为NULL且栈不空,则将栈顶节点出栈,
//同时置其右孩子为当前节点,循环判断,直至pCur不为空
while(!pCur && !is_empty(stack))
{
pCur = getTop(stack);
pop_stack(stack,&node_pop);
pCur = pCur->pRchild;
}
}
}
在理解过程中不是特别的顺畅 ,于是,同样利用栈实现,本人思路如下:
1)建立一个空栈。
2)将目标结点放置栈中。
3)输出结点数据域,弹出栈顶元素。
4)判断栈顶结点右结点是否为空,若不为空则加入栈中。
5)判断栈顶结点左结点是否为空,若不为空则加入栈中。
6)若栈不为空,则3,4,5步循环操作。
实现代码:
void preorder1(){
stack<Node*> st;
Node* cur = this;
st.push(cur);
while(!st.empty()){
cur = st.top();
cout << cur->data << " ";
st.pop();
if(cur->rchild != NULL){
st.push(cur->rchild);
}
if(cur->lchild != NULL){
st.push(cur->lchild);
}
}
}
得出结果:
demo建立: