二叉树的先序遍历,中序遍历和后序遍历递归算法以及非递归算法。层次遍历非递归算法。
二叉树的中序遍历与先序遍历或后序遍历建立二叉树递归算法以及非递归算法。
一些服务函数。(注:我喜欢把一些与算法无关的代码语句归类为服务,例如把string转成int,在一个数组内查找一个数据返回,这些只是为算法服务,去掉它们能更快理解算法。)
学数据结构以来打得最久的,投入在这个cpp文件的总时间超过24小时了。
#include<iostream>
#include<string>
#include<stack>
#include<queue>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define Status int
#define ElemType int
class TreeNode{
public:
ElemType data;
int num;
TreeNode *LeftChild;
TreeNode *RightChild;
TreeNode():LeftChild(NULL),RightChild(NULL){}
~TreeNode()
{
if(LeftChild)delete LeftChild;
if(RightChild)delete RightChild;
}//~TreeNode
};
//结点度是指一个结点拥有多少个子树
class Tree{
protected://————————————————————————protected
TreeNode *Root;
bool Find;//查找开关
bool Found;//判断是否找到指定编号的树叶
int pos;
ElemType *data;
Status setFindTrue();
Status setPosZero();
Status checkFind();
Status PrintResult();
//树结点指针 CreateBiTree((int)数组长度,(int)编号)
TreeNode* CreateBiTree(int ArraySize,int NUMBER);
//空 PreOrder((TreeNode*)树结点指针)
void PreOrder(TreeNode *t);//protected先序遍历输出树中所有的值
void InOrder(TreeNode *t);//protected中序遍历输出树中所有的值
void PostOrder(TreeNode *t);//protected后序遍历输出树中所有的值
void _PostOrder(TreeNode*t);
//状态 PreOrder((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void PreOrder(TreeNode*t,int n,TreeNode&_t);//先序遍历查找树指点编号的树叶
//空 PreOrderLeftChild((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void PreOrderLeftChild(TreeNode *t,int n,TreeNode *_t);//寻找编号插在其左结点
//空 PreOrderRightChild((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void PreOrderRightChild(TreeNode *t,int n,TreeNode*_t);//寻找编号插在其右结点
TreeNode* CreateTree(ElemType data[],int ArraySize);//浇水生长
void Non_Recursive_PreOrder(TreeNode*T); //protected非递归先序遍历
void Non_Recursive_IndexOrder(TreeNode*T); //protected非递归中序遍历
void Non_Recursive_PostOrder(TreeNode*T); //protected非递归后序遍历
void ClearTree(TreeNode*t);
Status LeftCheck(int num,ElemType data[]);
Status RightCheck(int num,int size,ElemType data[]);
void LevelOrder(TreeNode *t);//protected层次遍历
int search(ElemType ch,ElemType in_order[],int size);
void Recursive_PostIn_CreateBiTree(TreeNode *&t,int postindex,int inindex,int len,ElemType post_order[],ElemType in_order[],int in_order_size,int num);//递归算法根据后序遍历和中序遍历构建二叉树
void Recursive_PreIn_CreateBiTree(TreeNode *&t,int preindex,int inindex,int len,ElemType pre_order[],ElemType in_order[],int in_order_size,int num);//递归算法根据先序遍历和中序遍历构建二叉树
public://————————————————————————————————public
Status MakeNode(TreeNode *&t,ElemType data,bool New,int num);//状态 MakeNode(结点指针,数据,是否new,编号)
Status ClearTree(); //砍树
Status PreIn_CreateBiTree(ElemType Predata[],ElemType Indata[],int size);//非递归算法根据先序遍历和中序遍历来构建二叉树
Status PostIn_CreateBiTree(ElemType Postdata[],ElemType Indata[],int size);//非递归算法根据后序遍历和中序遍历来构建二叉树
Status Recursive_PostIn_CreateBiTree(ElemType post_order[],ElemType in_order[],int post_order_size);//递归算法根据先序遍历和中序遍历来构建二叉树
Status Recursive_PreIn_CreateBiTree(ElemType pre_order[],ElemType in_order[],int pre_order_size);//递归算法根据后序遍历和中序遍历来构建二叉树
//状态 InitTree((ElemType)数据数组,(int)数组长度)
Status InitTree(ElemType data[],int ArraySize);//种树
//空 PreOrder((bool)回车?)
void PreOrder(bool enter);//public先序遍历
void InOrder(bool enter);//public中序遍历
void PostOrder(bool enter);//public后序遍历
//状态 Findinformation((int)编号,(TreeNode&)返回主函数的树结点)
Status Findinformation(int n,TreeNode &_t);//根据指定编号查找结点
Status insertLeftChild(int n,TreeNode *_t);//根据指定编号查找结点,在其左孩子处插入树叶
Status insertRightChild(int n,TreeNode *_t);//根据指定编号查找结点,在其右孩子处插入树叶
Status Non_Recursive_PreOrder(bool enter);//非递归先序遍历
Status Non_Recursive_IndexOrder(bool enter);//非递归中序遍历
Status Non_Recursive_PostOrder(bool enter);//非递归后序遍历
Status Root_Empty();//判断树是否被砍了
void LevelOrder(bool enter);//public层次遍历
};//Tree
//————————————————————————————protected
Status Tree::setFindTrue()
{
Find=true;
Found=false;
return OK;
}//setFindTrue
Status Tree::setPosZero()
{
pos=0;
return OK;
}//setPosZero
Status Tree::checkFind()
{
if(Find)//没找到
{
Find=false;
}//if
else
{
Found=true;
}//else
PrintResult();
return TRUE;
}//checkFind
Status Tree::PrintResult()
{
if(Found==false)
{
cout<<"Not Found"<<endl;
return FALSE;
}//if
else
{
Found=false;
cout<<"Have Found"<<endl;
return TRUE;
}//else
}//PrintResult
//树结点指针 CreateBiTree((int)数组长度,(int)编号)
TreeNode* Tree::CreateBiTree(int ArraySize,int NUMBER)
{
TreeNode *T;
ElemType ch;
if(pos<ArraySize)ch=data[pos++];
if(ch==NULL)T=NULL;
else
{
T=new TreeNode();
T->data=ch;
T->num=NUMBER;
T->LeftChild=CreateBiTree(ArraySize,2*T->num);
T->RightChild=CreateBiTree(ArraySize,2*T->num+1);
}//else
return T;
}//CreateBiTree
//空 PreOrder((TreeNode*)树结点指针)
void Tree::PreOrder(TreeNode *t)//protected先序遍历输出树中所有的值
{
if(t)
{
cout<<t->data;
PreOrder(t->LeftChild);
PreOrder(t->RightChild);
}//if
}//PreOrder
void Tree::InOrder(TreeNode *t)//protected中序遍历输出树中所有的值
{
if(t)
{
InOrder(t->LeftChild);
cout<<t->data;
InOrder(t->RightChild);
}//if
}//InOrder
void Tree::PostOrder(TreeNode *t)//protected后序遍历输出树中所有的值
{
if(t)
{
PostOrder(t->LeftChild);
PostOrder(t->RightChild);
cout<<t->data;
}//if
}//PostOrder
void Tree::_PostOrder(TreeNode*t)
{
if(t)
{
_PostOrder(t->LeftChild);
_PostOrder(t->RightChild);
}
}//_PostOrder
//状态 PreOrder((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void Tree::PreOrder(TreeNode*t,int n,TreeNode&_t)//先序遍历查找树指点编号的树叶
{
if(t&&Find)
{
if(t->num==n) //找到指定编号的结点
{
_t=*t;
Find=false;//查找开关关闭
}//if
else
{
PreOrder(t->LeftChild,n,_t);
PreOrder(t->RightChild,n,_t);
}//else
}//if
}//PreOrder
//空 PreOrderLeftChild((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void Tree::PreOrderLeftChild(TreeNode *t,int n,TreeNode *_t)//寻找编号插在其左结点
{
if(t&&Find) //若t不为空且查找开关Find为True
{
if(t->num==n)
{
_t->num=t->num*2; //该结点的坐孩子的编号 = 该结点的编号*2
t->LeftChild=_t;
Find=false; //已找到,查找开关关闭。
}//if
else
{
PreOrderLeftChild(t->LeftChild,n,_t);
PreOrderLeftChild(t->RightChild,n,_t);
}//else
}//if
}//PreOrderLeftChild
//空 PreOrderRightChild((TreeNode*)树结点指针,(int)指定编号,(TreeNode&)返回主函数的树结点)
void Tree::PreOrderRightChild(TreeNode *t,int n,TreeNode*_t)//寻找编号插在其右结点
{
if(t&&Find)
{
if(t->num==n)
{
_t->num=t->num*2+1; //该结点的右孩子的编号 = 该结点的编号*2 + 1
t->RightChild=_t;
Find=false;
}//if
else
{
PreOrderRightChild(t->LeftChild,n,_t);
PreOrderRightChild(t->RightChild,n,_t);
}//else
}//if
}//PreOrderRightChild
TreeNode* Tree::CreateTree(ElemType data[],int ArraySize)//浇水生长
{
if(ArraySize==0)return NULL;
this->data=data;
setPosZero();
return CreateBiTree(ArraySize,1);
}//CreateTree
void Tree::Non_Recursive_PreOrder(TreeNode*T) //protected非递归先序遍历
{
/*——————————————————————————
首先进行p的输出。存储的内容基本上是右结点。
遍历左边缘不断输出,然后转到右结点入栈,继续
左边缘不断输出。等到再无左边缘的时候逆向输出
所有右孩子。
———————————————————————————*/
stack<TreeNode*> s;
TreeNode *p=T,*q;
s.push(p);//把Root推入栈内
while(!s.empty())//如果s不空
{
cout<<p->data;
q=p->RightChild;
if(q)s.push(q); //如果q(p的右孩子)不空则将q推入栈
p=p->LeftChild;
if(!p) //如果p(p的左孩子)为空则回到(p的右孩子)
{
p=s.top();
s.pop();
}//if
}//while
}//Non_recursive_PreOrder
void Tree::Non_Recursive_IndexOrder(TreeNode*T) //protected非递归中序遍历
{
/*————————————————————————————
首先不断遍历左边缘但不输出只入栈,
直到碰到NULL后(此时p=NULL)返回父结点输出父结点。
然后转到右结点入栈,继续遍历左边缘不输出
只入栈。一直编立到某个度为0的右结点的右孩子的时候
结束一支分支的遍历。
另一支分支的遍历相同。这一支分支的遍历
结束后中序遍历结束。
—————————————————————————————*/
stack<TreeNode*> s;
TreeNode *p=T;
s.push(NULL);
while(1)
{
while(p)
{
s.push(p); //栈是回溯法的主要工具
p=p->LeftChild;
}//while 遍历左边缘直到NULL
if(!s.top())break;//如果栈到达栈底则跳出
p=s.top();//p=NULL的时候返回其父结点或爷结点
s.pop();//弹出父结点
cout<<p->data;//输出父结点
p=p->RightChild;//调用父结点的右孩子
}//while
}//Non_recursive_IndexOrder
void Tree::Non_Recursive_PostOrder(TreeNode*T) //protected非递归后序遍历
{
/*——————————————————————————
先进行左边缘遍历,入栈,并记载访问次数为1(tag=0)。
直到p=NULL,然后返回父结点,父结点访问次数为2(tag=1)。
p转到父结点的右孩子。
重复以上步骤。
如果栈顶结点被第三次访问,则输出该结点,弹出。
———————————————————————————*/
stack<TreeNode*> s;//用于存储树结点
stack<bool>s1;//用于存储结点暂离状态
TreeNode *p=T;
s.push(NULL);//没有此句函数直接结束
while(1)//如果s不空
{
while(p)
{
s.push(p);
s1.push(false);
p=p->LeftChild;
}//while 用于存储左边缘树结点,全部暂离
if(s1.top())
{
p=s.top();
s1.pop();
s.pop();
cout<<p->data;
p=NULL;
}//if 第二次访问结点结点已待命,将结点和状态全部弹出,输出结点。令p=NULL,避免第四次读取结点。
else
{
s1.pop();
s1.push(true);
p=s.top()->RightChild;
}//else 如果结点是暂离,让其准备,当第二次碰见它时就输出。此时访问右孩子
if(!s.top())break;//如果栈到达栈底则跳出
}//while
}//Non_recursive_PostOrder
void Tree::ClearTree(TreeNode*t)
{
if(t)
{
_PostOrder(t->LeftChild);
_PostOrder(t->RightChild);
delete t;
}//if
}//ClearTree
Status Tree::LeftCheck(int num,ElemType data[])
{
if(num==0||data[num-1]==NULL)return FALSE;
return TRUE;
}//LeftCheck
Status Tree::RightCheck(int num,int size,ElemType data[])
{
if(num==size-1||data[num+1]==NULL)return FALSE;
return TRUE;
}//RightCheck
void Tree::LevelOrder(TreeNode *t)//protected层次遍历
{
/*——————————————————
读取每一层的时候把下一层存进队列中。
———————————————————*/
TreeNode *p=t;
queue<TreeNode*>q;
do
{
if(p)
{
cout<<p->data;
q.push(p->LeftChild);
q.push(p->RightChild);
}//if
p=q.front();
q.pop();
}//do
while(!q.empty());
}//LevelOrder
int Tree::search(ElemType ch,ElemType in_order[],int size)
{
int i;
for(i=0;i<size;i++)
{
if(ch==in_order[i])
{
return i;
}//if
}//for
return -1;
}
void Tree::Recursive_PostIn_CreateBiTree(TreeNode *&t,int postindex,int inindex,int len,ElemType post_order[],ElemType in_order[],int in_order_size,int num)//递归算法根据后序遍历和中序遍历构建二叉树
{
if(len<=0){t=NULL;return;}
//创建根节点(create the root node)
t=new TreeNode();
t->data=post_order[postindex];
t->num=num;
int index=search(t->data,in_order,in_order_size);
int lenf=index-inindex;
int lenr=len-1-lenf;
Recursive_PostIn_CreateBiTree(t->RightChild,postindex-1,index+1,lenr,post_order,in_order,in_order_size,2*num+1);
Recursive_PostIn_CreateBiTree(t->LeftChild,postindex-lenr-1,index-lenf,lenf,post_order,in_order,in_order_size,2*num);
}//Recursive_PostIn_CreateBiTree
void Tree::Recursive_PreIn_CreateBiTree(TreeNode *&t,int preindex,int inindex,int len,ElemType pre_order[],ElemType in_order[],int in_order_size,int num)
{
if(len<=0){t=NULL;return;}
//创建根节点(create the root node)
t=new TreeNode();
t->data=pre_order[preindex];
t->num=num;
int index=search(t->data,in_order,in_order_size);
int lenf=index-inindex;
int lenr=len-1-lenf;
Recursive_PreIn_CreateBiTree(t->LeftChild,preindex+1,index-lenf,lenf,pre_order,in_order,in_order_size,2*num);
Recursive_PreIn_CreateBiTree(t->RightChild,preindex+lenf+1,index+1,lenr,pre_order,in_order,in_order_size,2*num+1);
}//Recursive_PreIn_CreateBiTree
//————————————————————————————————————————————public
Status Tree::MakeNode(TreeNode *&t,ElemType data,bool New,int num)//状态 MakeNode(结点指针,数据,是否new,编号)
{
if(New)t=new TreeNode();
t->data=data;
t->num=num;
return OK;
}//MakeNode
Status Tree::ClearTree() //砍树
{
ClearTree(Root);
Root=NULL;
return OK;
}//ClearTree
Status Tree::PreIn_CreateBiTree(ElemType Predata[],ElemType Indata[],int size)//根据先序遍历和中序遍历来构建二叉树
{
if(!size)return ERROR;
int i=0,k;
stack<TreeNode*>s;
TreeNode *p;
Root=new TreeNode();
p=Root;
Root->num=1;
while(i<size)
{
for(k=0;k<size;k++)
{
if(Indata[k]==Predata[i])
{
if(LeftCheck(k,Indata))//前有
{
if(RightCheck(k,size,Indata))//后有
{
MakeNode(p,Predata[i++],false,p->num); //给p赋值Predata[i++]
MakeNode(p->LeftChild,NULL,true,p->num*2); //给p的左孩子新建并赋编号p->num*2
s.push(p);
p=p->LeftChild;
Indata[k]=NULL;
break;
}//if
else//后无
{
MakeNode(p,Predata[i++],false,p->num); //给p赋值Predata[i++]
MakeNode(p->LeftChild,NULL,true,p->num*2); //给p的左孩子新建并赋编号p->num*2
p=p->LeftChild;
Indata[k]=NULL;
break;
}//else
}//if
else//前无
{
if(RightCheck(k,size,Indata))//后有
{
MakeNode(p,Predata[i++],false,p->num); //给p赋值Predata[i++]
MakeNode(p->RightChild,NULL,true,p->num*2+1);//给p的右孩子新建并赋编号p->num*2+1
p=p->RightChild;
Indata[k]=NULL;
break;
}//if
else//后无
{
p->data=Predata[i++];
if(!s.empty())
{
MakeNode(s.top()->RightChild,NULL,true,s.top()->num*2+1);
p=s.top()->RightChild;
s.pop();
}//if
Indata[k]=NULL;
break;
}//else
}//else
}//if
}//for
}//while
return OK;
}//PreIn_CreateBiTree
Status Tree::PostIn_CreateBiTree(ElemType Postdata[],ElemType Indata[],int size)//根据后序遍历和中序遍历来构建二叉树
{
if(!size)return ERROR;
int i=size-1,k;
stack<TreeNode*>s;
TreeNode *p;
Root=new TreeNode();
p=Root;
Root->num=1;
while(i>=0)//后序遍历数组读取完毕
{
for(k=size-1;k>=0;k--)//读取中序遍历数组
{
if(Indata[k]==Postdata[i])
{
if(LeftCheck(k,Indata))//前有
{
if(RightCheck(k,size,Indata))//后有
{
MakeNode(p,Postdata[i--],false,p->num);
MakeNode(p->RightChild,NULL,true,p->num*2+1);
s.push(p);
p=p->RightChild;
Indata[k]=NULL;
break;
}//if
else//后无
{
MakeNode(p,Postdata[i--],false,p->num);
MakeNode(p->LeftChild,NULL,true,p->num*2);
p=p->LeftChild;
Indata[k]=NULL;
break;
}//else
}//if
else//前无
{
if(RightCheck(k,size,Indata))//后有
{
MakeNode(p,Postdata[i--],false,p->num);
MakeNode(p->RightChild,NULL,true,p->num*2+1);
p=p->RightChild;
Indata[k]=NULL;
break;
}//if
else//后无
{
p->data=Postdata[i--];
if(!s.empty())
{
MakeNode(s.top()->LeftChild,NULL,true,s.top()->num*2);
p=s.top()->LeftChild;
s.pop();
}
Indata[k]=NULL;
break;
}//else
}//else
}//if
}//for
}//while
return OK;
}//PostIn_CreateBiTree
Status Tree::Recursive_PostIn_CreateBiTree(ElemType post_order[],ElemType in_order[],int post_order_size)
{
Recursive_PostIn_CreateBiTree(Root,post_order_size-1,0,post_order_size,post_order,in_order,post_order_size,1);
return OK;
}//Recursive_PostIn_CreateBiTree
Status Tree::Recursive_PreIn_CreateBiTree(ElemType pre_order[],ElemType in_order[],int pre_order_size)
{
Recursive_PreIn_CreateBiTree(Root,0,0,pre_order_size,pre_order,in_order,pre_order_size,1);
return OK;
}//Recursive_PreIn_CreateBiTree
//状态 InitTree((ElemType)数据数组,(int)数组长度)
Status Tree::InitTree(ElemType data[],int ArraySize)//种树
{
Root=CreateTree(data,ArraySize);
Find=false;
Found=false;
return OK;
}//InitTree
//空 PreOrder((bool)回车?)
void Tree::PreOrder(bool enter)//public先序遍历
{
PreOrder(Root);
if(enter)cout<<endl;
}//PreOrder
void Tree::InOrder(bool enter)//public中序遍历
{
InOrder(Root);
if(enter)cout<<endl;
}//InOrder
void Tree::PostOrder(bool enter)//public后序遍历
{
PostOrder(Root);
if(enter)cout<<endl;
}//PostOrder
//状态 Findinformation((int)编号,(TreeNode&)返回主函数的树结点)
Status Tree::Findinformation(int n,TreeNode &_t)//根据指定编号查找结点
{
setFindTrue();//Find=true,Found=true;
PreOrder(Root,n,_t);
checkFind();
return OK;
}//Findinformation
Status Tree::insertLeftChild(int n,TreeNode *_t)//根据指定编号查找结点,在其左孩子处插入树叶
{
setFindTrue();
PreOrderLeftChild(Root,n,_t);
return OK;
}//insertLeftChild
Status Tree::insertRightChild(int n,TreeNode *_t)//根据指定编号查找结点,在其右孩子处插入树叶
{
setFindTrue();
PreOrderRightChild(Root,n,_t);
return OK;
}//insertRightChild
Status Tree::Non_Recursive_PreOrder(bool enter)//非递归先序遍历
{
Non_Recursive_PreOrder(Root);
if(enter)cout<<endl;
return OK;
}//Non_recursive_PreOrder
Status Tree::Non_Recursive_IndexOrder(bool enter)//非递归中序遍历
{
Non_Recursive_IndexOrder(Root);
if(enter)cout<<endl;
return OK;
}//Non_recursive_IndexOrder
Status Tree::Non_Recursive_PostOrder(bool enter)//非递归后序遍历
{
Non_Recursive_PostOrder(Root);
if(enter)cout<<endl;
return OK;
}//Non_Recursive_PostOrder
Status Tree::Root_Empty()//判断树是否被砍了
{
if(Root)return FALSE;
else return TRUE;
}//Root_Empty
void Tree::LevelOrder(bool enter)//public层次遍历
{
LevelOrder(Root);
if(enter)cout<<endl;
}//LevelOrder
int main()
{
ElemType data[9]={1,2,NULL,3,NULL,NULL,4,NULL,NULL};
Tree T1;
TreeNode treenode;
TreeNode *t;
T1.MakeNode(t,5,true,NULL);
T1.InitTree(data,9); //根据data和数组长度为9建立二叉树
T1.insertLeftChild(5,t); //在编号为5的树结点的左孩子插入数字5
T1.MakeNode(t,6,true,NULL);
T1.insertRightChild(5,t); //在编号为5的树结点的右孩子插入数字6
T1.MakeNode(t,9,true,NULL);
T1.insertLeftChild(10,t); //在编号为10的树结点的左孩子插入数字9
cout<<"Recursive Algorithm:"<<endl;
T1.PreOrder(true);
T1.InOrder(true);
T1.PostOrder(true);
cout<<"Non_Recursive Algorithm:"<<endl;
T1.Non_Recursive_PreOrder(true);
T1.Non_Recursive_IndexOrder(true);
T1.Non_Recursive_PostOrder(true);
T1.ClearTree();
cout<<T1.Root_Empty()<<endl;
ElemType data1[7]={1,2,4,7,6,3,5};
ElemType data2[7]={4,2,6,7,1,5,3};
ElemType data3[7]={4,6,7,2,5,3,1};
/* ElemType data1[7]={1,2,3,4,5,6,7};
ElemType data2[7]={7,6,5,4,3,2,1};
ElemType data3[7]={7,6,5,4,3,2,1};*/
/* ElemType data1[4]={5,9,67,32};
ElemType data2[4]={9,5,32,67};
ElemType data3[4]={9,32,67,5};*/
T1.PreIn_CreateBiTree(data1,data2,7); //非递归算法用后序遍历和中序遍历构建二叉树
T1.PreOrder(true);
T1.InOrder(true);
T1.PostOrder(true);
T1.LevelOrder(true);
T1.MakeNode(t,888,true,NULL);
T1.insertRightChild(3,t); //在编号为3的树结点的左孩子插入数字888
// T1.Recursive_PreIn_CreateBiTree(data1,data2,4);//递归算法用先序遍历和中序遍历构建二叉树
T1.Findinformation(7,treenode);
cout<<treenode.data<<" "<<treenode.num<<endl;
return 0;
}