根據前序和中序遍歷的結果建立二叉樹

題目是這樣的:設二叉樹的結點的數據場之值僅爲一大寫英文字母。其前序和中序的遍歷結果(打印結點的數據場之值)分別保存在字符串數組 preorder[N] 及 inorder[N]之中,其中 N 爲常數。請設計程序以標準形式形式存儲保存該二叉樹。

首先是二叉樹的構造。二叉樹的結點有一個數據域和兩個指針域組成,分別指向其左右子樹。以下是二叉樹類的聲明,主要包含負責建立和銷燬以及遍歷的函數。


template<class T>
struct BiNode
{
 T data;
 BiNode<T> *lchild,*rchild;
};

 

template<class T>
class BiTree
{
 public:
  BiTree();
  BiTree(string Pre,string In);
  ~BiTree();
  BiNode<T>* GetRoot() const;
  void PreOrder(BiNode<T> *root) const;
  void InOrder(BiNode<T> *root) const;
  void PostOrder(BiNode<T> *root) const;
  void LevelOrder(BiNode<T> *root) const;
 private:
  
  BiNode<T> *root;
  BiNode<T>* Creat(string Pre,string In);
  BiNode<T>* Creat();
  void Release(BiNode<T> *root);
}; 


二叉樹的建立銷燬和前序中序後序遍歷都是通過遞歸來實現的,其代碼如下。

 

二叉樹的建立:通過鍵盤輸入結點的數據建立二叉樹,輸入#結點爲空。


template<class T>
BiTree<T>::BiTree()
{
 this->root = Creat( );
}

 

template<class T>
BiNode<T>* BiTree<T>::Creat()
{
 BiNode<T>* root;
 T ch;
 cin>>ch;
    if (ch =='#')
  root = NULL;
    else{
      root = new BiNode<T>;       //生成一個結點
         root->data=ch;
         root->lchild = Creat( );    //遞歸建立左子樹
         root->rchild = Creat( );    //遞歸建立右子樹
    }
    return root;
}


使構造函數調用私有函數Creat(),再通過鍵盤輸入結點的數據建立二叉樹,輸入#結點爲空。

 

二叉樹的銷燬:


template<class T>
BiTree<T>::~BiTree()
{
 Release(root);
}

前序 中序 後序遍歷:
template<class T>
void BiTree<T>::PreOrder(BiNode<T> *root) const
{
 if(root==NULL)
  return;
 else
 {
  cout<<root->data<<" ";
  PreOrder(root->lchild);
  PreOrder(root->rchild);
 }
}

 


template<class T>
void BiTree<T>::InOrder(BiNode<T> *root) const
{
 if(root==NULL)
  return;
 else
 {
  InOrder(root->lchild);
  cout<<root->data<<" ";  
  InOrder(root->rchild);
 }
}


template<class T>
void BiTree<T>::PostOrder(BiNode<T> *root) const
{
 if(root==NULL)
  return;
 else
 {
  PostOrder(root->lchild);  
  PostOrder(root->rchild);
  cout<<root->data<<" "; 
 }
}

 


 

對於二叉樹的層序遍歷,是通過使用隊列來實現的。簡單的說就是若第k層的結點處於隊列中,在依次出隊和輸出其數據的同時,將其左右子結點(即k+1層的結點) 入隊。

 


 

template<class T>
void BiTree<T>::LevelOrder(BiNode<T> *root) const
{
 int front=0,rear=0;  //採用順序隊列,並假定不會發生上溢
 BiNode<T> *Q[100],*q;
 if(root==NULL)
  return;
 Q[++rear]=root;
 while(front!=rear)
 {
  q=Q[++front];
  cout<<q->data<<" ";
  if(q->lchild!=NULL)
   Q[++rear]=q->lchild;
  if(q->rchild!=NULL)
   Q[++rear]=q->rchild;
 }
 cout<<endl;
}

 


 

至此完成了二叉樹的基本構建。根據題目的要求,在此基礎上重載構造函數和私有函數Creat(),實現通過前序和中序遍歷的結果建立二叉樹。代碼如下:

 


 

template<class T>
BiTree<T>::BiTree(string Pre,string In)
{
 this->root=Creat(Pre,In);
}
template<class T>
BiNode<T>* BiTree<T>::Creat(string Pre,string In)

 BiNode<T> *root=new BiNode<T>;
 if(Pre.empty()==true)
 {
  root=NULL;
  return root;
 }

 string LeftPre,LeftIn,RightPre,RightIn;
 char strRoot;
 int mid,length;

 strRoot=Pre[0];  //在前序中找到根結點字符
 length=Pre.length();
 mid=In.find(strRoot,0);  //在中序中找到根結點字符的位置

 LeftIn=In.substr(0,mid); 
 RightIn=In.substr(mid+1,length-mid-1);
 LeftPre=Pre.substr(1,mid);
 RightPre=Pre.substr(mid+1,length-mid-1);

 root->data=strRoot;
 root->lchild=Creat(LeftPre,LeftIn);
 root->rchild=Creat(RightPre,RightIn);

 return root;
}


 

同樣使用了遞歸的方法將問題分治,在具體實現時藉助string類的方法拆分字符串後傳遞參數。

 

 


 

可以通過此鏈接下載本程序:http://cid-24fba8dfcc188fae.skydrive.live.com/self.aspx/Public/BinaryTree.rar

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章