ツリーは、共有ツリートラバーサルおよび判断にビルドに、多くの場合、今日使用される重要なデータ構造であり、主な成果は以下のとおりです。
- バイナリツリーを構築し、シーケンスの前順
- 構築バイナリシーケンスとそれに続きます
- 予約限定トラバーサル非再帰
- ためには、非再帰的トラバーサル
- 非再帰的トラバーサルシーケンス後
- レベル非再帰的トラバーサル
- バイナリツリーは完全2分木であるかどうかを確認
- バイナリツリーは完全なバイナリツリーであるかどうかを確認
- バイナリツリーは、バランスの取れた二分木であるかどうかを決定する
、次のように、コードに注釈を付け関連のアイデア:
# include <iostream>
using namespace std;
#include <cstdlib>
#include <stack>
#include <queue>
typedef struct Node
{
char data;
struct Node *lchild,*rchild;
}*BiTree,BiTreeNode;
//1.先序和中序创建树
BiTree PreInOrder(char preord[],char inord[],int i,int j,int k,int h)
{//先序从i,j,中序从k,h
BiTree t;
int m;
t=(BiTreeNode*)malloc(sizeof(BiTreeNode));
t->data=preord[i];//得到先序的根节点
m=k;
while(inord[m]!=preord[i])m++;//在中序序列中定位根节点
//递归调用建立左子树
if(m==k)//表示只有一个节点
t->lchild=NULL;
else
t->lchild=PreInOrder(preord,inord,i+1,i+m-k,k,m-1);
//递归调用建立右子树
if(m==h)
t->rchild=NULL;
else
t->rchild=PreInOrder(preord,inord,i+m-k+1,j,m+1,h);
return t;
}
//2.中序和后序
BiTree BehInOrder(char behord[],char inord[],int i,int j,int k,int h)
{//先序从i,j,中序从k,h
BiTree t;
int m;
t=(BiTreeNode*)malloc(sizeof(BiTreeNode));
t->data=behord[j];//得到后序的根节点
m=k;
while(inord[m]!=behord[j])m++;//在中序序列中定位根节点
//递归调用建立左子树
if(m==k)//表示只有一个节点
t->lchild=NULL;
else
t->lchild=BehInOrder(behord,inord,i,i+m-(k+1),k,m-1);
//递归调用建立右子树
if(m==h)
t->rchild=NULL;
else
t->rchild=BehInOrder(behord,inord,i+m-k,j-1,m+1,h);
return t;
}
BiTree CreateBiTree(char preord[],char inord[],int n)
{
BiTree root;
if(n<=0)
root=NULL;
else
//前+中root=PreInOrder(preord,inord,0,n-1,0,n-1);
//后+中
root=BehInOrder(preord,inord,0,n-1,0,n-1);
return root;
}
//3.非递归前序遍历(先输出,再进栈,遍历左子树完了到右边)
void Prorder(BiTree bt)
{
stack<BiTree>s;
BiTree p=bt;
while(p!=NULL||!s.empty())
{
if(p)
{
cout<<p->data<<" ";
s.push(p);
p=p->lchild;
}
else
{
p=s.top();
s.pop();
p=p->rchild;
}
}
cout<<endl;
}
//4.非递归中序遍历(栈实现,先进栈,遍历左子树,出栈时输出节点值,再遍历右子树,出栈输出)
void Inorder(BiTree bt)
{
stack<BiTree>s;
BiTree p=bt;
while(p!=NULL||!s.empty())
{
if(p)
{
s.push(p);
p=p->lchild;
}
else
{
p=s.top();
s.pop();
cout<<p->data<<" ";
p=p->rchild;
}
}
cout<<endl;
}
//5.非递归后序遍历(入栈带着标志,当节点标志为1,且没有孩子输出他)
void Beorder(BiTree bt)
{
stack<pair<BiTree,bool>> s;//栈里面放了一个二元结构体(利用pair),后面的是一个标志
BiTree p=bt;
while(p!=NULL||!s.empty())
{
if(p)
{
s.push(make_pair(p,false));//make_pair自动生成一个结构
p=p->lchild;
}
else//右子树未访问
{
if(s.top().second==false)
{
s.top().second=true;
p=s.top().first->rchild;
}
else//右子树已访问
{
cout<<s.top().first->data<<" ";
s.pop();
}
}
}
cout<<endl;
}
//6.非递归层次遍历(利用队列实现1.非空二叉树的根节点指针入队列2.队头元素出队,并输出,将该节点的左右孩子入队)
void LevelOrder(BiTree bt)
{
queue<BiTree> q;
BiTree p=NULL;
if(bt==NULL)
return;
q.push(bt);
while(!q.empty())
{
p=q.front();//p保存了q的队头元素,每次进行输出
q.pop();
cout<<p->data<<" ";
if(p->lchild)
q.push(p->lchild);//左孩子入队
if(p->rchild)
q.push(p->rchild);
}
cout<<endl;
}
//7.判断是否是满二叉树(用层次遍历做,每个节点都要左右孩子或者为叶节点)
bool IsFullBiTree(BiTree bt)
{
if(bt==NULL)
return false;
queue<BiTree>q;
BiTree p=NULL;
q.push(bt);
bool result=true;
while(!q.empty())
{
p=q.front();
q.pop();
if(p->lchild!=NULL&&p->rchild!=NULL)
{
q.push(p->lchild);
q.push(p->rchild);
}
else if(p->lchild==NULL&&p->rchild==NULL)
{
result=true;
}
else
{
result=false;
break;
}
}
return result;
}
//8.判断是否是完全二叉树(用层次遍历做1.可以只有左节点2.这个节点的双亲没有右节点,它不能有左右孩子)
bool IsCompleteBiTree(BiTree bt)
{
if(bt==NULL)
return false;
queue<BiTree>q;
BiTree p=NULL;
q.push(bt);
bool ifchild=false;
bool result=true;
while(!q.empty())
{
p=q.front();
q.pop();
if(ifchild)//双亲没有右孩子只有左孩子,则这个节点不能有孩子
{
if(p->lchild!=NULL||p->rchild!=NULL)
{
result=false;
break;
}
}
else
{
if(p->lchild!=NULL&&p->rchild!=NULL)
{
q.push(p->lchild);
q.push(p->rchild);
}
else if(p->lchild!=NULL&&p->rchild==NULL)
{
ifchild=true;
q.push(p->lchild);
}
else if(p->lchild==NULL&&p->rchild!=NULL)
{
result=false;
break;
}
else
{
ifchild=true;
}
}
}
return result;
}
//9.判断是否是平衡二叉树(用到了求树深度的函数,左子树为平衡树,右子树为平衡树,左右子树的高度相差不为1)
//(1)时间复杂度高,节点被重复访问
int TreeDepth(BiTree bt)//求深度的函数
{
if(bt==NULL)
{
return 0;
}
int left=TreeDepth(bt->lchild);
int right=TreeDepth(bt->rchild);
return (left>right)?(left+1):(right+1);
}
bool IsBlanced(BiTree bt)
{
if(bt==NULL)
{
return true;
}
int left=TreeDepth(bt->lchild);
int right=TreeDepth(bt->rchild);
int diff=left-right;
if(diff>1||diff<-1)
{
return false;
}
return IsBlanced(bt->lchild)&&IsBlanced(bt->rchild);
}
//(2)在每次遍历的时候就求出节点的深度,这样避免了重复访问节点
bool IsBalanced2(BiTree bt,int *depth)
{
if(bt==NULL)
{
*depth=0;
return true;
}
int left,right;
if(IsBalanced2(bt->lchild,&left)&&IsBalanced2(bt->rchild,&right))//左子树和右子树都是平衡树
{
int diff=left-right;
if(diff<=1&&diff>=-1)
{
*depth=1+(left>right?left:right);
return true;
}
}
return false;
}
int main()
{
//char str1[40]={"ABCDEFG"};//前
//char str2[40]={"CBDAEGF"};//中
//char str3[40]={"CDBGFEA"};//后
/*char str1[40]={"1248950367"};//前
char str2[40]={"8492051637"};//中
char str3[40]={"8940526731"};//后*/
char str1[40]={"1243"};//前
char str2[40]={"4213"};//中
char str3[40]={"4231"};//后
int n=strlen(str1);
BiTree root;
root=CreateBiTree(str3,str2,n);
cout<<"前序:"<<str1<<endl;
cout<<"中序:"<<str2<<endl;
cout<<"后序:"<<str3<<endl;
cout<<"层次遍历输出"<<endl;
LevelOrder(root);
cout<<"前序遍历输出"<<endl;
Prorder(root);
cout<<"中序遍历输出"<<endl;
Inorder(root);
cout<<"后序遍历输出"<<endl;
Beorder(root);
if(IsCompleteBiTree(root))
{
cout<<"是完全二叉树"<<endl;
}
else
cout<<"不是完全二叉树"<<endl;
if(IsFullBiTree(root))
{
cout<<"是满二叉树"<<endl;
}
else
cout<<"不是满二叉树"<<endl;
if(IsBlanced(root))
{
cout<<"是平衡二叉树"<<endl;
}
else
cout<<"不是平衡二叉树"<<endl;
int depth=0;
if(IsBalanced2(root,&depth))
{
cout<<"是平衡二叉树,深度为:"<<depth<<endl;
}
else
cout<<"不是平衡二叉树,深度为:"<<depth<<endl;
}
スクリーンショットは、その結果を操作する:
新人1、間違っている場合、神はああ指摘を歓迎します!さあ!