二叉树的先序,中序,后序,层次,递归,非递归遍历
2014-06-02 17:53
661 查看
关于二叉树的遍历,递归遍历的话,就只要不断的递归就够啦,而非递归的话就需要用到栈和队列了,然而栈和队列也是我自己写的吧,就算是锻炼了一下自己对数据结构课的掌握吧,而非递归后序遍历二叉树参考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。
一、先序遍历二叉树
1.递归遍历
每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。
2.非递归遍历
判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。
二、中序遍历二叉树
1.递归遍历
每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。
2.非递归遍历
思路基本和先序差不多,只是输出数据的时候不一样。判断栈和树是否为空,若不,则判断树是否为空,不为继续将左子树进栈,若为空,则出栈,输出数据,然后访问右子树。
三、后序遍历二叉树
1.递归遍历
先判断树是否为空,若不为,先左子树,后右子树,然后根节点。
2.非递归遍历
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
四、层次遍历二叉树
建立一个队列,先将根节点入队,然后将队首出队,然后判断它的左右子树是否为空,不为空,则先将左子树入队,然后右子树入队。
贴上我自己的全部代码,自己以后可以看,希望或许对别人也有帮助吧,表达能力不行,嘿嘿。
给一个二叉树参考例子:
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
一、先序遍历二叉树
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
相关文章推荐
- 二叉树的遍历:先序,中序,后序,递归,非递归,层次遍历
- 【基础备忘】二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 采用二叉链表结构实现二叉树,并以递归遍历思想实现二叉树的创建、二叉树的遍历(先序、中序、后序和层次遍历)
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(一)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- (1)建立二叉树的二叉链表。 (2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。 (3)写出对用二叉链表存储的二叉树进行层次遍历算法。 (4)求二叉树的所有叶子及结点总数。
- 用java实现二叉树的前序、中序、后序、层次遍历(递归和非递归版)
- 二叉树的前序、中序、后序、层次遍历的递归与非递归实现
- 二叉树的前中后层次遍历(递归+非递归)、创建树(数组、前序+中序、中序加后序)
- 二叉树的先序,中序,后序,层次的递归及非递归遍历
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- python实现二叉树的建立以及遍历(递归前序、中序、后序遍历,队栈前序、中序、后序、层次遍历)
- 用非递归实现二叉树的前序、中序、后序、层次遍历,用递归实现查找、统计个数、比较、求深度
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- java 实现二叉树的构建,先序,中序,后序,层次,递归,非递归的遍历