花了很久完成了这个非递归实现树的遍历的代码,中间在堆栈的使用方面出了一些问题,耽误了很久,最后在后序遍历上也纠结了很久。现在,把代码分享一下:
/*
************************************************
*Name : Bittree all operation
*Date : 2014-12-18
*Author : marksman
*Aim : Create a bittree and visit it.
************************************************
*/
#include <stdio.h>
#include <stdlib.h>
#define stack_size 100
/*
*Tree structure
*/
typedef struct
{
char data;
struct tree *lchild,*rchild;
}tree,*Bit_tree;
/*
*Create the bittree
*/
Bit_tree Create_bit_tree(Bit_tree bittree)
{
char ch;
scanf("%c",&ch);
getchar();
if(ch=='$')
bittree = NULL;
else
{
bittree = (tree *)malloc(sizeof(tree));
bittree->data = ch;
bittree->lchild = Create_bit_tree(bittree->lchild);
bittree->rchild = Create_bit_tree(bittree->rchild);
}
return bittree;
}
/*
*preorder the bittree
*/
int preorder_bit_tree(Bit_tree bittree)
{
if(bittree)
{
printf("%c ",bittree->data);
preorder_bit_tree(bittree->lchild);
preorder_bit_tree(bittree->rchild);
}
return 0;
}
/*
*inorder the bittree
*/
int inorder_bit_tree(Bit_tree bittree)
{
if(bittree!=NULL)
{
inorder_bit_tree(bittree->lchild);
printf("%c ",bittree->data);
inorder_bit_tree(bittree->rchild);
}
return 0;
}
/*
*beorder the bittree
*/
int beorder_bit_tree(Bit_tree bittree)
{
if(bittree!=NULL)
{
beorder_bit_tree(bittree->lchild);
beorder_bit_tree(bittree->rchild);
printf("%c ",bittree->data);
}
return 0;
}
/*
*build a Immoblization bottom stack
*Push order is from bottom to top
*/
typedef struct
{
int top;
int bottom;
tree *buf[stack_size];
}stack,*stack_point;
/*
*Operation of stack
*/
/*
*Initiablization of stack
*/
stack_point init_stack(stack_point stp)
{
stp = (stack *)malloc(sizeof(stack));
stp->top = 0;
stp->bottom = stp->top;
return stp;
}
/*
*Push of stack
*/
void push(stack_point stp,Bit_tree bittree)
{
if(stp->top>=stack_size)
{
printf("stack overflow!\n");
return 1;
}
stp->buf[stp->top] = (tree *)malloc(sizeof(tree));
stp->buf[stp->top] = bittree;
stp->top++;
}
/*
*Pop of stack
*/
Bit_tree pop(stack_point stp)
{
stp->top--;
return stp->buf[stp->top];
}
/*
*stack status
*/
int stack_status(stack_point stp)
{
if(stp->top ==0 && stp->bottom == stp->top)
{
return 1;
}
return 0;
}
/*
*top of stack
*/
Bit_tree stack_top(stack_point stp)
{
if (stp->top<=0)
return NULL;
return stp->buf[stp->top-1];
}
/*
*preorder of tree unrecursion
*/
/*
*For the node P:
*Firstly, visiting the node P,and push the node P into stack
*Secondly,Checking the node P's left child is NULL or not,
* if this node is NULL,get the top of stack and push it.
* At the end,put the current node P's right child become
* current node P,and do the first step.If this node is not
* NULL,put the left child become the current node P.
*Thirdly,when the node P is NULL and the stack is NULL.It's
* over.
*/
/*
* 对于任一结点P:
*1)访问结点P,并将结点P入栈;
*2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈
* 操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不
* 为空,则将P的左孩子置为当前的结点P;
*3)直到P为NULL并且栈为空,则遍历结束。
*/
void preorder_unrecursion(Bit_tree bit)
{
stack_point stp;
Bit_tree bittree;
bittree = bit;
stp = init_stack(stp);
while(bittree || !stack_status(stp))
{
while(bittree)
{
printf("%c ",bittree->data);
push(stp,bittree);
bittree = bittree->lchild;
}
if(!stack_status(stp))
{
bittree = stack_top(stp);
pop(stp);
bittree = bittree ->rchild;
}
}
}
/*
*Inorder of tree unrecursion
*/
/*
*For the node P:
*First, if his left child not NULL,then put his left
* child into the stack and put his left child become
* current node. For the current node do same things
* like the node P.
*Second,if his left child is NULL, then get the top
* of stack and pop the element.Printing the element.At
* the end, put the node P's right child become the
* current node P.
*Third,when the node P is NULL.It's over.
*/
/*
* 对于任一结点P,
*1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,
* 然后对当前结点P再进行相同的处理;
*2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该
* 栈顶结点,然后将当前的P置为栈顶结点的右孩子;
*3)直到P为NULL并且栈为空则遍历结束
*/
void Inorder_unrecursion(Bit_tree bt)
{
stack_point stp;
Bit_tree bittree;
stp = init_stack(stp);
bittree = bt;
while(bittree || !stack_status(stp))
{
while(bittree)
{
push(stp,bittree);
bittree = bittree->lchild;
}
if(!stack_status(stp))
{
bittree = stack_top(stp);
printf("%c ",bittree->data);
pop(stp);
bittree = bittree->rchild;
}
}
}
/*
*Postorder of tree unrecursion
*/
/*
*I think visit the tree in postorder is very difficult.
*First , when the node's leftchild is NULL,you can not
*pop the node.Checking the right child NULL or not. If
*the node's left child and right child is NULL.Print
*the node.Second if the node's left child or right
*child is not NULL.But the right or child has been
*visited.You can print this node.If not these condition,
*you should push the node into the stack.
*/
/*
*因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
*则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩
*子和右孩子都已被访问过了,则同样可以直接访问该结点。
*若非上述两种情况,则将P的右孩子和左孩子依次入栈。
*/
void Postorder_unrecursion(Bit_tree bt)
{
stack_point stp;
Bit_tree bittree;
Bit_tree cur;
Bit_tree pre;
cur = bt;
pre=(tree *)malloc(sizeof(tree));
stp=init_stack(stp);
bittree = bt;
push(stp,bittree);
while(!stack_status(stp))
{
cur = stack_top(stp);
if((cur->lchild==NULL && cur->rchild==NULL) \
|| (pre!=NULL && (pre == cur->lchild || pre == cur->rchild)))
{
printf("%c ",cur->data);
pop(stp);
pre = cur;
}
else
{
if(cur ->rchild !=NULL)
push(stp,cur->rchild);
if(cur ->lchild !=NULL)
push(stp,cur->lchild);
}
}
}
int main()
{
Bit_tree bittree;
bittree = (tree *)malloc(sizeof(tree));
bittree = Create_bit_tree(bittree);
printf("Visitting the tree : \n");
preorder_bit_tree(bittree);
printf("\n");
inorder_bit_tree(bittree);
printf("\n");
beorder_bit_tree(bittree);
printf("\n");
printf("Unrecursion travel : \n");
preorder_unrecursion(bittree);
printf("\n");
Inorder_unrecursion(bittree);
printf("\n");
Postorder_unrecursion(bittree);
printf("\n");
return 0;
}
测试用例:
A
B
C
$
$
D
E
$
G
$
$
F
$
$
$
输出结果:
对于遍历的思路参考了:
http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html
在这里把他分享给大家!对于思路方面的问题我习惯用英文注释,所以翻译了一下,但是限于英文水平有限,怕翻译的不准,只能把中文标上,对于这个翻译方面出的问题,望大家见谅。