还是数据结构的一个作业。
实现先序,中序,后序的递归,非递归遍历以及层序遍历。
递归代码量很小,可是想起来可是相当的难。
非递归的算法都是根据递归步骤来的,不过后序遍历的非递归算法着实让我弄了半天啊,还是有点复杂的。
层序遍历利用的队列,特别的巧妙。
再次先发明这些方法的人致敬啊,真心太有智慧了。
包含一个主文件和几个头文件。
main.cpp
#include <iostream>
#include "CreateBTREE.h"
#include "STACK.h"
#include "STACK_post_order.h"
#include "QUEUE_loop_array.h"
using namespace std;
void PreOrder(BTREE BT) ;
void noneRecursive_PreOrder(BTREE BT ,STACK & S) ;
void InOrder(BTREE BT ) ;
void noneRecursive_InOrder(BTREE BT , STACK& S) ;
void PostOrder(BTREE BT) ;
void noneRecursive_PostOrder(BTREE BT,STACK_PO & S) ;
void LevelOrder(BTREE BT,QUEUE & Q) ;
int main()
{
cout <<"\t\t树的各种遍历方式\n\n" ;
BTREE BT ;
string lists ;
cout <<"\n先建立树:\n" ;
CreateBTREE(BT,lists) ;
modifyLists(lists) ;
string menu = "\n\n选择遍历的方式:\n1.递归-先序遍历\t2.非递归-先序遍历\n" ;
menu+="3.递归-中序遍历\t4.非递归-中序遍历\n" ;
menu+="5.递归-后序遍历\t6.非递归-后序遍历\n" ;
menu+="7.层序遍历\n8.退出\n\n" ;
STACK S ;
STACK_PO S_PO ;
QUEUE Q ;
while(cout <<menu)
{
char choice ;
cin >>choice ;
switch(choice)
{
case '1' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n递归先序遍历的结果序列为:\n\n" ;
PreOrder(BT) ;
break ;
case '2' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n非递归先序遍历的结果序列为:\n\n" ;
noneRecursive_PreOrder(BT,S) ;
break ;
case '3' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n递归中序遍历的结果序列为:\n\n" ;
InOrder(BT) ;
break ;
case '4' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n非递归中序遍历的结果序列为:\n\n" ;
noneRecursive_InOrder(BT,S) ;
break ;
case '5' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n递归后序遍历的结果序列为:\n\n" ;
PostOrder(BT) ;
break ;
case '6' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n非递归后序遍历的结果序列为:\n\n" ;
noneRecursive_PostOrder(BT,S_PO) ;
break ;
case '7' :
cout <<"建立的树为:"<<lists <<endl ;
cout <<"\n层序遍历的结果序列为:\n\n" ;
LevelOrder(BT,Q) ;
break ;
default:
cout <<"无效的选项。\n" ;
break ;
}
}
return 0;
}
//递归先序遍历
void PreOrder(BTREE BT)
{
if(BT != NULL)
{
cout <<BT->data <<" ";
PreOrder(BT->lChild) ;
PreOrder(BT->rChild) ;
}
}
//非递归先序遍历
void noneRecursive_PreOrder(BTREE BT ,STACK & S)
{
MakeNull(S) ;
while(BT!= NULL || !isEmpty(S))
{
if(BT!= NULL)
{
cout <<BT->data <<" " ;
Push(BT,S) ;
BT = BT->lChild ;
}
else
{
if(!isEmpty(S))
{
BT = Pop(S) ;
BT = BT->rChild ;
}
}
}
}
//递归中序遍历
void InOrder(BTREE BT )
{
if(BT != NULL)
{
InOrder(BT->lChild) ;
cout <<BT->data <<" " ;
InOrder(BT->rChild) ;
}
}
//非递归中序遍历
void noneRecursive_InOrder(BTREE BT , STACK& S)
{
MakeNull(S) ;
while(BT!= NULL || !isEmpty(S))
{
if(BT!= NULL)
{
Push(BT,S) ;
BT = BT->lChild ;
}
else
{
if(!isEmpty(S))
{
BT = Pop(S) ;
cout <<BT->data <<" " ;
BT = BT->rChild ;
}
}
}
}
//递归后序遍历
void PostOrder(BTREE BT)
{
if(BT!=NULL)
{
PostOrder(BT->lChild) ;
PostOrder(BT->rChild) ;
cout <<BT->data<<" " ;
}
}
//非递归后序遍历
void noneRecursive_PostOrder(BTREE BT,STACK_PO & S)
{
MakeNull(S) ;
while(BT!= NULL || !isEmpty(S))
{
if(BT!= NULL)
{
Push(BT,S) ;
BT = BT->lChild ;
}
else
{
if(!isEmpty(S))
{
BT = Top(S) ;
//一定要把把已经标示右节点已被读取的节点全部读出并Pop掉
while(!isEmpty(S)&&isRChildVisited(S))
{
cout <<BT->data <<" " ;
Pop(S) ;
BT = Top(S) ;
}
//现在栈顶元素一定是右节点未被访问且即将访问其右节点
if(!isEmpty(S))
{
changeRFlag(S) ;
BT = BT->rChild ;
}
}
}
}
}
//层序遍历
void LevelOrder(BTREE BT,QUEUE & Q)
{
MakeNull(Q) ;
if(BT != NULL)
{
cout <<BT->data <<" " ;
EnQueue(BT,Q) ;
while(!isEmpty(Q))
{
BT = Front(Q) ;
DeQueue(Q) ;
if(BT->lChild!= NULL)
{
cout <<BT->lChild->data <<" " ;
EnQueue(BT->lChild,Q) ;
}
if(BT->rChild!= NULL)
{
cout <<BT->rChild->data <<" " ;
EnQueue(BT->rChild,Q) ;
}
}
}
}
头文件就不列出来了。