您的位置:首页 > 其它

二叉树的先序,中序,后序,层次,递归,非递归遍历

2014-06-02 17:53 661 查看
关于二叉树的遍历,递归遍历的话,就只要不断的递归就够啦,而非递归的话就需要用到栈和队列了,然而栈和队列也是我自己写的吧,就算是锻炼了一下自己对数据结构课的掌握吧,而非递归后序遍历二叉树参考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。

一、先序遍历二叉树

1.递归遍历

每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。

/*二叉树递归先序遍历*/
void PreTraverseTree1(TreeNode * T)
{
if(T)
{
printf("%c  ", T->data) ;
PreTraverseTree1(T->leftchild) ;
PreTraverseTree1(T->rightchild) ;
}
}


2.非递归遍历

判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。

/*二叉树的非递归先序遍历*/
void PreTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * p ;
S = NULL ;
p = T ;
S = InitStack(S) ;

if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

while(p || !StackEmpty(S))
{
if(p)
{
StackPush(S, p) ;
printf("%c  ", p->data) ;
p = p->leftchild ;
}
else
{
StackPop(S, p) ;
p = p->rightchild ;
}
}

free(S) ;
}


二、中序遍历二叉树

1.递归遍历

每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。

/*二叉树递归中序遍历*/
void InOrderTraverseTree1(TreeNode * T)
{
if(T)
{
InOrderTraverseTree1(T->leftchild) ;
printf("%c  ", T->data) ;
InOrderTraverseTree1(T->rightchild) ;
}
}


2.非递归遍历

思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。

/*二叉树的非递归中序遍历*/
void InOrderTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * p ;
S = NULL ;
p = T ;
S = InitStack(S) ;

if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

while(p || !StackEmpty(S))
{
if(p)
{
StackPush(S, p) ;
p = p->leftchild ;
}
else
{
StackPop(S, p) ;
printf("%c  ", p->data) ;
p = p->rightchild ;
}
}
free(S) ;
}


三、后序遍历二叉树

1.递归遍历

先判断树是否为空,若不为,先左子树,后右子树,然后根节点。

/*二叉树递归后序遍历*/
void LastTraverseTree1(TreeNode * T)
{
if(T)
{
LastTraverseTree1(T->leftchild) ;
LastTraverseTree1(T->rightchild) ;
printf("%c  ", T->data) ;
}
}


2.非递归遍历

要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

/*二叉树非递归后序遍历*/
void LastTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * cur, * pre ;
S = NULL ;
S = InitStack(S) ;
if(NULL == T)
{
printf("树为空!\n") ;
return ;
}

pre = NULL ;    cur = NULL ;
StackPush(S,T) ;
while(!StackEmpty(S))
{
cur = NULL ;
StackGetTop(S,cur) ;
if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
{
printf("%c  ", cur->data) ;
pre = cur ;
StackPop(S,cur) ;
}
else
{
if(cur->rightchild != NULL)
{
StackPush(S,cur->rightchild) ;
}
if(cur->leftchild != NULL)
{
StackPush(S,cur->leftchild) ;
}
}
}
free(S) ;
}


四、层次遍历二叉树

建立一个队列,先将根节点入队,然后将队首出队,然后判断它的左右子树是否为空,不为空,则先将左子树入队,然后右子树入队。

/*二叉树层次遍历*/
void LevelTraverseTree(TreeNode * T)
{
QueueHead * Q ;
TreeNode * p ;
Q = NULL ;    p = T ;
Q = InitQueue(Q) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

QueuePush(Q,p) ;
while(!QueueEmpty(Q))
{
p = NULL ;
QueuePop(Q,p) ;

if(NULL != p->leftchild)
QueuePush(Q,p->leftchild) ;

if(NULL != p->rightchild)
QueuePush(Q,p->rightchild) ;

printf("%c  ", p->data) ;
}
}


贴上我自己的全部代码,自己以后可以看,希望或许对别人也有帮助吧,表达能力不行,嘿嘿。

#include <stdio.h>
#include <stdlib.h>

typedef struct treenode      //树的节点
{
char data ;
treenode * leftchild, * rightchild ;
}TreeNode;

typedef TreeNode * StackElemType ;   //定义栈包含的数据类型

typedef struct stacknode    //栈的节点
{
StackElemType data ;
stacknode * next ;
}StackNode;

typedef TreeNode * QueueElemType ;     //定义队列包含的数据类型

typedef struct queuenode     //定义队列节点
{
QueueElemType  data ;
struct queuenode * next ;
}QueueNode;

typedef struct queuehead    //定义队列的头节点
{
QueueNode * front, * rear ;
}QueueHead;

//stack的有关声明
StackNode * InitStack(StackNode * S) ;
void StackPush(StackNode * S, StackElemType data) ;
void StackPop(StackNode * S, StackElemType & data) ;
int StackEmpty(StackNode * S) ;
int StackGetTop(StackNode * S, StackElemType & data) ;

//queue的有关声明
QueueHead * InitQueue(QueueHead * Q) ;
void QueuePush(QueueHead * Q, QueueElemType data) ;
void QueuePop(QueueHead * Q, QueueElemType & data) ;
int QueueEmpty(QueueHead * Q) ;

//TreeTraverse的有关声明
TreeNode * InitTree(TreeNode * T) ;
void PreTraverseTree1(TreeNode * T) ;
void PreTraverseTree2(TreeNode * T) ;
void InOrderTraverseTree1(TreeNode * T) ;
void InOrderTraverseTree2(TreeNode * T) ;
void LastTraverseTree1(TreeNode * T) ;
void LastTraverseTree2(TreeNode * T) ;
void LevelTraverseTree(TreeNode * T) ;

//栈的函数定义
StackNode * InitStack(StackNode * S)
{
S = (StackNode *)malloc(sizeof(StackNode)) ;
if(NULL == S)
{
printf("内存不足,不能分配栈!\n") ;
exit(0) ;
}

S->next = NULL ;
return(S) ;
}

void StackPush(StackNode * S, StackElemType data)
{
StackNode * q ;
q = (StackNode *)malloc(sizeof(StackNode)) ;
if(NULL == q)
{
printf("内存不足,不能分配栈!\n") ;
exit(0) ;
}
q->data = data ;
q->next = S->next ;
S->next = q ;
}

void StackPop(StackNode * S, StackElemType & data)
{
StackNode * q ;
if(NULL == S->next)
{
printf("栈为空,无返回值!\n") ;
}

q = S->next ;
data = q->data ;
S->next = q->next ;
free(q) ;
}

int StackEmpty(StackNode * S)
{
if(NULL == S->next)
{
return(1) ;
}

return(0) ;
}

int StackGetTop(StackNode * S, StackElemType & data)
{
if(NULL != S->next)
{
data = S->next->data ;
return(1) ;
}
else
{
//data = NULL ;
return(0) ;
}
}

//队列函数的定义
QueueHead * InitQueue(QueueHead * Q)
{
QueueNode * q ;
Q = (QueueHead *)malloc(sizeof(QueueHead)) ;
if(NULL == Q)
{
printf("内存不足!\n") ;
exit(0) ;
}
q = (QueueNode *)malloc(sizeof(QueueNode)) ;
if(NULL == q)
{
printf("内存不足!\n") ;
exit(0) ;
}

q->next = NULL ;
Q->front = q ;
Q->rear = q ;

return(Q) ;
}

void QueuePush(QueueHead * Q, QueueElemType data)
{
QueueNode * q ;
q = (QueueNode *)malloc(sizeof(QueueNode)) ;
if(NULL == q)
{
printf("内存不足!\n") ;
exit(0) ;
}

q->data = data ;
q->next = Q->rear->next ;
Q->rear->next = q ;
Q->rear = q ;
}

void QueuePop(QueueHead * Q, QueueElemType & data)
{
QueueNode * q ;
if(Q->front == Q->rear)
{
printf("队列为空!\n") ;
return ;
}

q = Q->front->next ;
data = q->data ;
Q->front->next = q->next ;
if(Q->rear == q)
Q->rear = Q->front ;

free(q) ;
}

int QueueEmpty(QueueHead * Q)
{
if(Q->front == Q->rear)
return(1) ;
else
return(0) ;
}

//树的各种遍历函数定义

/*建立一棵二叉树*/
TreeNode * InitTree(TreeNode * T)
{
char data ;
scanf("%c", &data) ;

if('#' == data)
{
T = NULL ;
}
else
{
T = (TreeNode *)malloc(sizeof(TreeNode)) ;
T->data = data ;
T->leftchild = InitTree(T->leftchild) ;
T->rightchild = InitTree(T->rightchild) ;
}

return(T) ;
}

/*二叉树递归先序遍历*/
void PreTraverseTree1(TreeNode * T)
{
if(T)
{
printf("%c  ", T->data) ;
PreTraverseTree1(T->leftchild) ;
PreTraverseTree1(T->rightchild) ;
}
}

/*二叉树的非递归先序遍历*/
void PreTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * p ;
S = NULL ;
p = T ;
S = InitStack(S) ;

if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

while(p || !StackEmpty(S))
{
if(p)
{
StackPush(S, p) ;
printf("%c  ", p->data) ;
p = p->leftchild ;
}
else
{
StackPop(S, p) ;
p = p->rightchild ;
}
}

free(S) ;
}

/*二叉树递归中序遍历*/
void InOrderTraverseTree1(TreeNode * T)
{
if(T)
{
InOrderTraverseTree1(T->leftchild) ;
printf("%c  ", T->data) ;
InOrderTraverseTree1(T->rightchild) ;
}
}

/*二叉树的非递归中序遍历*/
void InOrderTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * p ;
S = NULL ;
p = T ;
S = InitStack(S) ;

if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

while(p || !StackEmpty(S))
{
if(p)
{
StackPush(S, p) ;
p = p->leftchild ;
}
else
{
StackPop(S, p) ;
printf("%c  ", p->data) ;
p = p->rightchild ;
}
}
free(S) ;
}

/*二叉树递归后序遍历*/
void LastTraverseTree1(TreeNode * T)
{
if(T)
{
LastTraverseTree1(T->leftchild) ;
LastTraverseTree1(T->rightchild) ;
printf("%c  ", T->data) ;
}
}

/*二叉树非递归后序遍历*/
void LastTraverseTree2(TreeNode * T)
{
StackNode * S ;
TreeNode * cur, * pre ;
S = NULL ;
S = InitStack(S) ;
if(NULL == T)
{
printf("树为空!\n") ;
return ;
}

pre = NULL ;    cur = NULL ;
StackPush(S,T) ;
while(!StackEmpty(S))
{
cur = NULL ;
StackGetTop(S,cur) ;
if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild)))
{
printf("%c  ", cur->data) ;
pre = cur ;
StackPop(S,cur) ;
}
else
{
if(cur->rightchild != NULL)
{
StackPush(S,cur->rightchild) ;
}
if(cur->leftchild != NULL)
{
StackPush(S,cur->leftchild) ;
}
}
}
free(S) ;
}

/*二叉树层次遍历*/
void LevelTraverseTree(TreeNode * T)
{
QueueHead * Q ;
TreeNode * p ;
Q = NULL ;    p = T ;
Q = InitQueue(Q) ;
if(NULL == p)
{
printf("树为空!\n") ;
return ;
}

QueuePush(Q,p) ;
while(!QueueEmpty(Q))
{
p = NULL ;
QueuePop(Q,p) ;

if(NULL != p->leftchild)
QueuePush(Q,p->leftchild) ;

if(NULL != p->rightchild)
QueuePush(Q,p->rightchild) ;

printf("%c  ", p->data) ;
}
}

//主函数的定义
void Tips()
{
printf("建立树是按照先序遍历来建立树的,并且输入‘#’表示子树为空。\n") ;
printf("请输入要建立的树:") ;
}

int main()
{
TreeNode * T ;
T = NULL ;

Tips() ;

T = InitTree(T) ;

printf("二叉树递归先序遍历\n") ;
PreTraverseTree1(T) ;
printf("\n") ;

printf("二叉树非递归先序遍历\n") ;
PreTraverseTree2(T) ;
printf("\n") ;

printf("二叉树递归中序遍历\n") ;
InOrderTraverseTree1(T) ;
printf("\n") ;

printf("二叉树非递归中序遍历\n") ;
InOrderTraverseTree2(T) ;
printf("\n") ;

printf("二叉树递归后序遍历\n") ;
LastTraverseTree1(T) ;
printf("\n") ;

printf("二叉树非递归后序遍历\n") ;
LastTraverseTree2(T) ;
printf("\n") ;

printf("二叉树层次遍历\n") ;
LevelTraverseTree(T) ;
printf("\n") ;

return 0 ;
}


给一个二叉树参考例子:

a

b c

d e

输入:abd##e##c##

输出:

二叉树先序递归遍历:a b d e c

二叉树先序非递归遍历:a b d e c

二叉树中序递归遍历:d b e a c

二叉树中序非递归遍历:d b e a c

二叉树后序递归遍历:d e b c a

二叉树后序非递归遍历:d e b c a

二叉树层次遍历:a b c d e
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐