前序,中序,後序,廣度的非遞歸程序實現

早學完了二叉樹。也知道了前序,中序,後序,廣度的非遞歸是怎麼實現的。但是一直沒有寫出程序出來。今天週末就把他寫出來了,我覺得這些程序都很容易理解。所有沒寫什麼註釋了,這是用C++實現的。在棧是用STL種的棧實現的。如果大家用C語言編寫,就一定要記得把它的棧寫出來纔可以實現。在整個程序中比較難理解的就是找父親結點的算法和後序非遞歸實現的A,B。仔細理解還是看的懂的。程序我在VC6.0中實現的。其他編譯器就不能保證了。

程序如下:

//                                        二叉樹的建立。
//前序,中序,後序,廣度的非遞歸程序實現。
#include <iostream>
#include <stack>
#include <queue>

using namespace std;

enum Tags{Left,Right};

 

template <class Elem>
class TreeNode
{
 public:
  TreeNode* left;
  TreeNode* right;
  Elem data;
  TreeNode(Elem dataval,TreeNode* leftval=NULL,TreeNode* rightval=NULL)
  {
   data=dataval;
   left=leftval;
   right=rightval;
  }
  TreeNode(TreeNode* leftval=NULL,TreeNode* rightval=NULL)
  {
   left=leftval;
   right=rightval;
  }
  ~TreeNode(){}
};

template<class Elem>
class StackElement
{
 public:
  TreeNode<Elem>* pointer;
  Tags tag;
};

template<class Elem>
class BinTree
{
 public:
  BinTree()
  {
   init();
  }
  ~BinTree()
  {
   DeleteTree(root);
  }
  //初始化根結點。
  void init();
  //後序遞歸刪除二叉樹。
  void DeleteTree(TreeNode<Elem>*);
  //有前序遞歸創建二叉樹。
  TreeNode<Elem>* Create();
  //前序非遞歸遍歷。
  void PreOrder(TreeNode<Elem>*);
        //中序非遞歸遍歷。
  void PreOrderWithoutRecusion(TreeNode<Elem>*);
  //後序非遞歸遍歷。
  void InOrderWithoutRecusion(TreeNode<Elem>*);
  //後序非遞歸遍歷。另一種版本
     void PostOrderWithoutRecusion(TreeNode<Elem>*);
  //廣度優先遍歷。
  void LevelOrder(TreeNode<Elem>*);
  //操作函數。
     void Massage(TreeNode<Elem>*);
  //查找父親結點
  TreeNode<Elem>* GetParent(TreeNode<Elem>* root,TreeNode<Elem>* current);
  //返回父親結點的指針。
  TreeNode<Elem>* Parent(TreeNode<Elem>* current);
 private:
  TreeNode<Elem>* root;
};

template<class Elem>
void BinTree<Elem>::init()
{
 root=new TreeNode<Elem>;
}

template<class Elem>
void BinTree<Elem>::DeleteTree(TreeNode<Elem>* T)
{
 if(T!=NULL)
 {
  DeleteTree(T->left);
  DeleteTree(T->right);
  delete T;
 }
}

template<class Elem>
TreeNode<Elem>* BinTree<Elem>:: Create()
{
 TreeNode<Elem>* T;
 char ch;
 cin>>ch;
 if(ch=='#')
  T=NULL;
 else
 {
  T=new TreeNode<Elem>(ch,NULL,NULL);
  T->left=Create();
  T->right=Create();
 }
 return T;
}

template <class Elem>
void BinTree<Elem>::Massage(TreeNode<Elem>* T)
{
 cout<<T->data<<" ";
}

template<class Elem>
void BinTree<Elem>::PreOrder(TreeNode<Elem>* T)
{
 using std::stack;
 stack<TreeNode<Elem>*> aStack;
 TreeNode<Elem>* point=T;
 while(!aStack.empty()||point!=NULL)
 {
  if(point!=NULL)
  {
   Massage(point);
   aStack.push(point);
   point=point->left;
  }
  else
  {
   point=aStack.top();
   aStack.pop();
   point=point->right;
  }//end else
 }//end while
}

template<class Elem>
void BinTree<Elem>::PreOrderWithoutRecusion(TreeNode<Elem>*T)
{
 using std::stack;
 stack<TreeNode<Elem>*> aStack;
 TreeNode<Elem>* point=T;
 while(point!=NULL||!aStack.empty())
 {
  if(point!=NULL)
  {
      aStack.push(point);
      point=point->left;
  }
     else
  {
   point=aStack.top();
   Massage(point);
   point=point->right;
   aStack.pop();
  }//end else
 }//end while
}

template<class Elem>
void BinTree<Elem>::InOrderWithoutRecusion(TreeNode<Elem>* T)
{
    using std::stack;
 StackElement<Elem> element;
 stack<StackElement<Elem> > aStack;
 TreeNode<Elem>* point;
 if(T==NULL)
  return;
 else
  point=T;
 while(true)
 {
  //從左邊進。
  while(point!=NULL)
  {
   element.pointer=point;
   element.tag=Left;
   aStack.push(element);
   point=point->left;
  }
  element=aStack.top();
  aStack.pop();
  point=element.pointer;
  //從右邊進。
  while(element.tag==Right)
  {
   Massage(point);
   if(aStack.empty())
    return;
   else
   {
    element=aStack.top();
    aStack.pop();
    point=element.pointer;
   }//end else
  }//end while
  element.tag=Right;
  aStack.push(element);
  point=point->right;
 }//end while
}

template<class Elem>
void BinTree<Elem>::PostOrderWithoutRecusion(TreeNode<Elem>* T)
{
 using std::stack;
 stack<TreeNode<Elem>*> aStack;
 TreeNode<Elem> *p,*q;
 if(T==NULL)
  return;
 p=T;
 do
 {
  while(p!=NULL)
  {
   aStack.push(p);
            p=p->left;
  }
  q=NULL;
  while(!aStack.empty())
  {
   p=aStack.top();
   aStack.pop();
   if(p->right==q)         //右子樹爲空或剛剛訪問過。
   {
    Massage(p);
    q=p;
   }//end if
   else
   {
    aStack.push(p);
    p=p->right;
    break;
   }//end else
  }//end while
 }while(!aStack.empty());
}

template<class Elem>
void BinTree<Elem>::LevelOrder(TreeNode<Elem>* T)
{
 using std::queue;
 queue<TreeNode<Elem>*> aQueue;
 TreeNode<Elem>* point=T;
 if(point!=NULL)
  aQueue.push(point);
 while(!aQueue.empty())
 {
  point=aQueue.front();
  Massage(point);
  aQueue.pop();
  if(point->left!=NULL)
   aQueue.push(point->left);
  if(point->right!=NULL)
   aQueue.push(point->right);
 }//end while
}

template<class Elem>
TreeNode<Elem>* BinTree<Elem>::GetParent(TreeNode<Elem>* root,
           TreeNode<Elem>* current)
{
 TreeNode<Elem>* temp;
 if(root==NULL)
  return NULL;
 //找到父結點。
 if(root->left==current || root->right==current)
  return root;
    //用遞歸找父結點。
 if((temp=GetParent(root->left,current))!=NULL)
        return temp;
 else
  return GetParent(root->right,current)
}

template<class Elem>
TreeNode<Elem>* BinTree<Elem>::Parent(TreeNode<Elem>* T)
{
 if(current==NULL||current==T)
  return NULL;
 else
  return GetParent(T,current);//遞歸調用函數找到父結點。
}

//主函數實現。
int main()
{
 BinTree<char> A;
 TreeNode<char> *Troot;
 cout<<"輸入字符串:#代表的是空樹:"<<endl;
 Troot=A.Create();
 cout<<"前序遍歷:";
 A.PreOrder(Troot);
 cout<<"/n中序遍歷:";
 A.PreOrderWithoutRecusion(Troot);
 cout<<"/n後序遍歷A:";
 A.InOrderWithoutRecusion(Troot);
 cout<<"/n後序遍歷B: ";
 A.PostOrderWithoutRecusion(Troot);
 cout<<"/n廣度優先遍歷:";
 A.LevelOrder(Troot);
 cout<<endl;
 return 0;
}
//輸入:

// 輸入字符串:#代表的是空樹:
// a
// b
// c
// #
// #
// d
// e
// #
// g
// #
// #
// f
// #
// #
// #

//輸出樣例:

//前序遍歷:a b c d e g f
//中序遍歷:c b e g d f a
//後序遍歷A:c g e f d b a
//後序遍歷B: c g e f d b a
//廣度優先遍歷:a b c d e f g

//程序結束。

我這裏寫出來。對與那些還沒有理解和不知道怎麼編寫整個程序的同學借鑑和學習。

 

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