二叉树前中后序遍历的递归版本和非递归版本、队列实现的层次遍历
2015-04-12 23:39
621 查看
/* 数据结构分析与学习专栏 * Copyright (c) 2015, 山东大学 计算机科学与技术专业 学生 * All rights reserved. * 作 者: 高祥 * 完成日期: 2015 年 4 月 12 日 * 版 本 号:018 *任务描述:针对二叉树遍历,实现7种方法 * 1:层次遍历二叉树 ; * 2:先序遍历二叉树递归实现 ; * 3:中序遍历二叉树递归实现; * 4:后序遍历二叉树递归实现 ; * 5:先序遍历二叉树非递归实现; * 6:中序遍历二叉树非递归实现 ; * 7:后序遍历二叉树非递归实现 ; *主要函数: * 1.void CreateByPreOrder(BinaryTree &T);//给定完整的先序遍历建树 * 2.void LevelTraverse(BinaryTree T);//层次遍历 * 3.void PreOrderTraverse1(BinaryTree T);//先序遍历递归实现 * 4.void InOrderTraverse1(BinaryTree T);//中序遍历递归实现 * 5.void PostOrderTraverse1(BinaryTree T);//后序遍历递归实现 * 6.void PreOrderTraverse2(BinaryTree T);//先序遍历非递归实现 * 7.void InOrderTraverse2(BinaryTree T);//中序遍历非递归实现 * 8.void PostOrderTraverse2(BinaryTree T);//后序遍历非递归实现 *运行示例 请输入某棵二叉树的先序遍历(若某结点的左/右子结点不存在,用‘#’表示): ABC##DE#G##F### 层序遍历为: A B C D E F G 递归版本的先、中、后序遍历: 先序遍历为: A B C D E G F 中序遍历为: C B E G D F A 后序遍历为: C G E F D B A 非递归版本的先、中、后序遍历: 先序遍历为: A B C D E G F 中序遍历为: C B E G D F A 后序遍历为: C G E F D B A 是否继续程序?请输入Y/N(分别代表是、否):Y 请输入某棵二叉树的先序遍历(若某结点的左/右子结点不存在,用‘#’表示): ABD##EF#G###CH#J##I#K## 层序遍历为: A B C D E H I F J K G 递归版本的先、中、后序遍历: 先序遍历为: A B D E F G C H J I K 中序遍历为: D B F G E A H J C I K 后序遍历为: D G F E B J H K I C A 非递归版本的先、中、后序遍历: 先序遍历为: A B D E F G C H J I K 中序遍历为: D B F G E A H J C I K 后序遍历为: D G F E B J H K I C A 是否继续程序?请输入Y/N(分别代表是、否):N */ #include<iostream> #include<queue> #include<stack> #include<cstdlib> using namespace std; typedef char ElemType; typedef struct BTNode//二叉树结点类型 { ElemType data; struct BTNode *leftchild; struct BTNode *rightchild; } BTNode,*BinaryTree; void CreateByPreOrder(BinaryTree &T);//给定完整的先序遍历建树 void LevelTraverse(BinaryTree T);//层次遍历 void PreOrderTraverse1(BinaryTree T);//先序遍历递归实现 void InOrderTraverse1(BinaryTree T);//中序遍历递归实现 void PostOrderTraverse1(BinaryTree T);//后序遍历递归实现 void PreOrderTraverse2(BinaryTree T);//先序遍历非递归实现 void InOrderTraverse2(BinaryTree T);//中序遍历非递归实现 void PostOrderTraverse2(BinaryTree T);//后序遍历非递归实现 int main() { char operate='y'; while(operate=='y'||operate=='Y') { BinaryTree T; cout<<"请输入某棵二叉树的先序遍历(若某结点的左/右子结点不存在,用‘#’表示):\n"; CreateByPreOrder(T); cout<<"层序遍历为:\n"; LevelTraverse(T); cout<<"\n递归版本的先、中、后序遍历:\n"; cout<<"\n先序遍历为:\n"; PreOrderTraverse1(T); cout<<"\n中序遍历为:\n"; InOrderTraverse1(T); cout<<"\n后序遍历为:\n"; PostOrderTraverse1(T); cout<<"\n\n非递归版本的先、中、后序遍历:\n"; cout<<"\n先序遍历为:\n"; PreOrderTraverse2(T); cout<<"\n中序遍历为:\n"; InOrderTraverse2(T); cout<<"\n后序遍历为:\n"; PostOrderTraverse2(T); cout<<"\n\n是否继续程序?请输入Y/N(分别代表是、否):"; cin>>operate; } return 0; } void CreateByPreOrder(BinaryTree &T)//给定完整的先序遍历建树 { ElemType ch; cin>>ch; if(ch=='#') { T=NULL;//空结点 } else { T=(BinaryTree)malloc(sizeof(BTNode));//建立根结点 T->data=ch; CreateByPreOrder(T->leftchild);//建立当前根结点的左子结点 CreateByPreOrder(T->rightchild);//建立当前根结点的右子结点 } } void LevelTraverse(BinaryTree T)//层次遍历 { if(T) { //利用数据结构队列实现:首先将根结点入队。在队列不为空的前提下: //取出队列首元素T,输出其值并删除队列首元素,若T的左子结点存在,将其入队; //若T的右子结点存在,将其入队。重复该过程直至队列为空。 queue<BinaryTree> Q; Q.push(T);//根结点入队 while(!Q.empty())//在队列不为空的前提下 { BinaryTree now=Q.front();//取出队列首元素T cout<<now->data<<" ";//输出其值 Q.pop();//删除队列首元素 if(now->leftchild)//若T的左子结点存在,将其入队 { Q.push(now->leftchild); } if(now->rightchild)//若T的右子结点存在,将其入队 { Q.push(now->rightchild); } } cout<<endl; } } void PreOrderTraverse1(BinaryTree T)//先序遍历递归实现 { if(T) { cout<<T->data<<" ";//访问根结点 PreOrderTraverse1(T->leftchild);//访问左子结点 PreOrderTraverse1(T->rightchild);//访问右子结点 } } void InOrderTraverse1(BinaryTree T)//中序遍历递归实现 { if(T) { InOrderTraverse1(T->leftchild);//访问左子结点 cout<<T->data<<" ";//访问根结点 InOrderTraverse1(T->rightchild);//访问右子结点 } } void PostOrderTraverse1(BinaryTree T)//先序遍历递归实现 { if(T) { PostOrderTraverse1(T->leftchild);//访问左子结点 PostOrderTraverse1(T->rightchild);//访问右子结点 cout<<T->data<<" ";//访问根结点 } } void PreOrderTraverse2(BinaryTree T)//先序遍历非递归实现 { stack<BinaryTree> s; while(!s.empty()||T) { while(T) { cout<<T->data<<" ";//访问根结点 s.push(T);//压入访问过的根结点 T=T->leftchild;//访问当前根结点的左子结点 } //至此为止:所有栈内的结点及其左子结点均已访问完毕 T=s.top();//取出最后访问过的根结点 s.pop();//删除栈首元素 T=T->rightchild;//将当前根结点的右子结点更新为新的根结点(如果存在的话) } } void InOrderTraverse2(BinaryTree T)//中序遍历非递归实现 { stack<BinaryTree> s; while(!s.empty()||T) { while(T) { s.push(T);//压入根结点但不访问 T=T->leftchild;//将当前根结点的左子结点更新为新的根结点(如果存在的话) } //至此为止:所有栈内的结点的左子结点均已访问完毕 T=s.top();//取出最后压入的根结点(该根结点的左子结点为空) cout<<T->data<<" ";//访问该根结点 s.pop();//栈首元素出栈 T=T->rightchild;//将当前根结点的右子结点更新为新的根结点(如果存在的话) } } void PostOrderTraverse2(BinaryTree T)//后序遍历非递归实现 { //后序遍历中,二叉树的根结点需要其左右子树都遍历结束后才能访问,需要两个栈来辅助解决 stack<BinaryTree> s;//指针栈来存放所经过的根结点的指针 stack<int> num;//辅助栈用来记录某根结点被路过的次数 while(T||!s.empty()) { while(T) { s.push(T);//压入根结点不访问 num.push(1);//第一次路过该根结点 T=T->leftchild;//将当前根结点的左子结点更新为新的根结点(如果存在的话) } if(!num.empty())//辅助栈非空时 { if(num.top()==1) { num.top()=2;//第二次路过当前根结点 T=s.top();//取出该根结点 T=T->rightchild;//将当前根结点的右子结点更新为新的根结点(如果存在的话) } else//第三次路过该当前根结点 { T=s.top();//取出根结点 s.pop();//指针栈删除栈首元素 num.pop();//辅助栈删除栈首元素 cout<<T->data<<" ";//访问当前根结点 T=NULL;//将访问过的结点置空 } } } }
相关文章推荐
- 遍历二叉树——递归和非递归(栈和队列的应用)实现
- 用非递归实现二叉树的前序、中序、后序、层次遍历,用递归实现查找、统计个数、比较、求深度
- 二叉树的建立,前中后序遍历的递归版本和非递归版本,层序遍历
- java语言实现二叉树的前序、中序与后序遍历(递归与非递归) 层次遍历
- 二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
- 二叉树(利用栈和队列实现递归和非递归遍历,构建等)
- 二叉排序树节点的删除(C++,算法导论),前中后序遍历(递归/非递归,栈实现),按层次遍历(队列实现)
- 二叉树的建立&&前中后遍历(递归实现)&&层次遍历
- [二叉树专题]:广度优先:按层次遍历二叉树的非递归实现||使用队列实现层次遍历二叉树
- java实现二叉树的前中后遍历(递归和非递归)
- 数据结构 利用循环队列层次遍历一棵二叉树 递归实现
- 43 递归和非递归俩种方法实现二叉树的三种遍历
- 用java实现二叉树的前序、中序、后序、层次遍历(递归和非递归版)
- 超级详细的二叉树的3种遍历方法的递归和非递归的实现
- 二叉树按层次遍历--队列实现
- 二叉树按层次遍历--队列实现
- 二叉树构建以及前中后序遍历(递归和非递归)Java实现
- 数据结构(一)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 前中后序遍历二叉树的非递归实现
- 采用二叉链表结构实现二叉树,并以递归遍历思想实现二叉树的创建、二叉树的遍历(先序、中序、后序和层次遍历)