一, 二叉树先序遍历的实现
- 递归实现
void PreOrderTraverse(BiTree T)
{
if( T )
{
VisitF(T->data);//访问根节点
PreOrderTraverse(T->lchild);//递归左子树
PreOrderTraverse(T->rchild);//递归右子树
}
}
2. 非递归实现
思路:
- 判断栈是否为空或子树为空
- 若不为空,就访问左孩子并将其入栈,直至左孩子为空
- 若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。
void PreOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree p ;
S = NULL ;
p = T ;
InitStack(S) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}
while(p || !StackEmpty(S))
{
if(p)
{
Push(S, p) ;
VisitF(p->data);
p = p->lchild ;
}
else
{
Pop(S, p) ;
p = p->rchild ;
}
}
free(S) ;
}
二, 二叉树中序遍历的实现
- 递归实现
/*
中序遍历二叉树
*/
void InOrderTraverse(BiTree T)
{
if( T )
{
InOrderTraverse(T->lchild);
VisitF(T->data);
InOrderTraverse(T->rchild);
}
}
2. 非递归实现
思路:思路基本和先序差不多,只是输出数据的时候不一样
-
判断栈和树是否为空,
-
若不,则判断树是否为空,
-
不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。
void InOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree p ;
S = NULL ;
p = T ;
InitStack(S) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}
while(p || !StackEmpty(S))
{
if(p)
{
Push(S, p) ;
p = p->lchild ;
}
else
{
Pop(S, p) ;
VisitF(p->data);
p = p->rchild ;
}
}
free(S) ;
}
三, 二叉树中序遍历的实现
- 递归实现
/*
后续遍历二叉树
*/
void PostOrderTraverse(BiTree T)
{
if( T )
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
VisitF(T->data);
}
}
2. 非递归实现
思路 :实现有多多种方法,有两个栈,或加标志位实现,但是我觉得如下实现最容易懂
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
void PostOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree cur, pre ;
S = NULL ;
InitStack(S) ;
if(NULL == T)
{
printf("树为空!\n") ;
return ;
}
pre = NULL ;
cur = NULL ;
Push(S,T) ;
while(!StackEmpty(S))
{
cur = NULL ;
GetTop(S,cur) ;
if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild ||pre == cur->rchild)))
{
VisitF(cur->data);
pre = cur ;
Pop(S,cur) ;
}
else
{
if(cur->rchild != NULL)
{
Push(S,cur->rchild) ;
}
if(cur->lchild != NULL)
{
Push(S,cur->lchild) ;
}
}
}
free(S) ;
}
如下是完整代码:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR -1
typedef char TElemType;
typedef int Status;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode,*BiTree;
typedef BiTNode * StackElemType;
typedef struct LinkNode //栈的节点
{
StackElemType data ;
LinkNode * next ;
} LinkNode,*LiStack;
typedef BiTNode * QueueElemType ; //定义队列包含的数据类型
typedef struct QNode //定义队列节点
{
QueueElemType data ;
struct QNode * next ;
} QNode,*QueuePtr;
typedef struct
{
QueuePtr fronts;
QueuePtr rears;
} LinkQueue;
Status creatBiTree(BiTree &T);
void Visit(char ch,int level);
void PreOrderTraverse(BiTree T,int level);
void InOrderTraverse(BiTree T,int level);
void PostOrderTraverse(BiTree T,int level);
Status InitStack(LiStack &S);
void Push(LiStack &S, StackElemType data);
void Pop(LiStack & S, StackElemType &data);
int StackEmpty(LiStack &S);
int GetTop(LiStack &S, StackElemType & data);
Status InitQueue(LinkQueue &Q);
Status EnQueue(LinkQueue &Q, QueueElemType data);
Status DeQueue(LinkQueue &Q, QueueElemType & data);
int QueueEmpty(LinkQueue Q);
void PreOrderTraverse_Nonrecursion(BiTree T);
void InOrderTraverse_Nonrecursion(BiTree T);
void PostOrderTraverse_Nonrecursion(BiTree T);
/*********************************************************************/
/*****************************栈的方法********************************/
//栈的函数定义
Status InitStack(LiStack &S)
{
S = (LinkNode *)malloc(sizeof(LinkNode)) ;
if(NULL == S)
{
printf("内存不足,不能分配栈!\n") ;
exit(0) ;
}
S->next = NULL ;
}
void Push(LiStack &S, StackElemType data)
{
LiStack q ;
q = (LinkNode *)malloc(sizeof(LinkNode)) ;
if(NULL == q)
{
printf("内存不足,不能分配栈!\n") ;
exit(0) ;
}
/*
插入顺序相当于头插法.
*/
q->data = data ;
q->next = S->next ;
S->next = q ;
}
void Pop(LiStack & S, StackElemType &data)
{
LiStack q;
if(NULL == S->next)
{
printf("栈为空,无返回值!\n") ;
}
q = S->next ;
data = q->data ;
S->next = q->next ;
free(q) ;
}
int StackEmpty(LiStack &S)
{
if(NULL == S->next)
{
return(1) ;
}
return(0) ;
}
int GetTop(LiStack &S, StackElemType & data)
{
if(NULL != S->next)
{
data = S->next->data ;
return(1) ;
}
else
{
//data = NULL ;
return(0) ;
}
}
/*********************************************************************/
/*****************************队列的方法******************************/
//队列函数的定义
Status InitQueue(LinkQueue &Q)
{
Q.fronts = Q.rears = (QNode *)malloc(sizeof(QNode)) ;
if(NULL == Q.fronts)
{
printf("内存不足!\n") ;
return ERROR;
}
Q.fronts->next = NULL;
}
Status EnQueue(LinkQueue &Q, QueueElemType data)
{
QueuePtr q ;
q = (QNode*)malloc(sizeof(QNode));
if(NULL == q)
{
printf("内存不足!\n") ;
return ERROR;
}
//构造q
q->data = data ;
q->next = NULL;
q->next = Q.rears->next ;
Q.rears = q ;
return OK;
}
Status DeQueue(LinkQueue &Q, QueueElemType & data)
{
QueuePtr p ;
if(Q.fronts == Q.rears)
{
printf("队列为空!\n") ;
return ERROR ;
}
p = Q.fronts->next ;
data = p->data ;
Q.fronts->next = p->next ;
if(Q.rears == p)
Q.rears = Q.fronts ;
free(p);
return OK;
}
int QueueEmpty(LinkQueue Q)
{
if(Q.fronts == Q.rears)
return(1) ;
else
return(0) ;
}
/*********************************************************************/
/*
先序创建二叉树
*/
Status creatBiTree(BiTree &T)
{
char ch;
scanf("%c",&ch);
if('@' == ch)
{
T = NULL;
}
else
{
//申请失败
if(!(T = (BiTNode*)malloc(sizeof(BiTNode))))
return ERROR;
T->data = ch;
creatBiTree(T->lchild);
creatBiTree(T->rchild);
}
return OK;
}
void VisitF(char ch)
{
printf("%c ",ch);
}
void Visit(char ch,int level)
{
printf("%c 位于第 %d 层 \n",ch,level);
}
/*
先序遍历二叉树
*/
void PreOrderTraverse(BiTree T,int level)
{
if( T )
{
VisitF(T->data);
PreOrderTraverse(T->lchild,++level);
PreOrderTraverse(T->rchild,++level);
}
}
void PreOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree p ;
S = NULL ;
p = T ;
InitStack(S) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}
while(p || !StackEmpty(S))
{
if(p)
{
Push(S, p) ;
VisitF(p->data);
p = p->lchild ;
}
else
{
Pop(S, p) ;
p = p->rchild ;
}
}
free(S) ;
}
/*
中序遍历二叉树
*/
void InOrderTraverse(BiTree T)
{
if( T )
{
InOrderTraverse(T->lchild);
VisitF(T->data);
InOrderTraverse(T->rchild);
}
}
void InOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree p ;
S = NULL ;
p = T ;
InitStack(S) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}
while(p || !StackEmpty(S))
{
if(p)
{
Push(S, p) ;
p = p->lchild ;
}
else
{
Pop(S, p) ;
VisitF(p->data);
p = p->rchild ;
}
}
free(S) ;
}
/*
后续遍历二叉树
*/
void PostOrderTraverse(BiTree T)
{
if( T )
{
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
VisitF(T->data);
}
}
void PostOrderTraverse_Nonrecursion(BiTree T)
{
LiStack S ;
BiTree cur, pre ;
S = NULL ;
InitStack(S) ;
if(NULL == T)
{
printf("树为空!\n") ;
return ;
}
pre = NULL ;
cur = NULL ;
Push(S,T) ;
while(!StackEmpty(S))
{
cur = NULL ;
GetTop(S,cur) ;
if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild ||pre == cur->rchild)))
{
VisitF(cur->data);
pre = cur ;
Pop(S,cur) ;
}
else
{
if(cur->rchild != NULL)
{
Push(S,cur->rchild) ;
}
if(cur->lchild != NULL)
{
Push(S,cur->lchild) ;
}
}
}
free(S) ;
}
int main()
{
int level = 1;
BiTree T = NULL;
creatBiTree(T);
printf("先序遍历二叉树,每个结点在第几行\n");
PreOrderTraverse(T,level);
printf("\n\n");
printf("先序遍历二叉树,非递归算法\n");
PreOrderTraverse_Nonrecursion(T);
printf("\n\n\n");
/***************************************************/
printf("中序遍历二叉树\n");
InOrderTraverse(T);
printf("\n\n");
printf("中序遍历二叉树,非递归算法\n");
InOrderTraverse_Nonrecursion(T);
printf("\n\n\n");
/***************************************************/
printf("后序遍历二叉树\n");
PostOrderTraverse(T);
printf("\n\n");
printf("后序遍历二叉树,非递归算法\n");
PostOrderTraverse_Nonrecursion(T);
printf("\n\n\n");
return 0;
}