ツリートラバーサルと決意を構築

ツリーは、共有ツリートラバーサルおよび判断にビルドに、多くの場合、今日使用される重要なデータ構造であり、主な成果は以下のとおりです。

  • バイナリツリーを構築し、シーケンスの前順
  • 構築バイナリシーケンスとそれに続きます
  • 予約限定トラバーサル非再帰
  • ためには、非再帰的トラバーサル
  • 非再帰的トラバーサルシーケンス後
  • レベル非再帰的トラバーサル
  • バイナリツリーは完全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、間違っている場合、神はああ指摘を歓迎します!さあ!

公開された54元の記事 ウォンの賞賛8 ビュー5319

おすすめ

転載: blog.csdn.net/qq_43411555/article/details/103090935