二叉樹

        在介紹二叉樹之前大家一定要對樹有一定的瞭解,二叉樹是一種特殊的樹結構,二叉樹每個節點最多有兩個孩子節點,分別爲左孩子和右孩子。

  *滿二叉樹高度爲N的滿二叉樹有2^n-1個節點的二叉樹。

  *完全二叉樹:若設二叉樹的深度爲h,除第h層外,其他各層(1~h-1)的節點數都達到最大個數,第h層所有的節點都連續集中在最左邊,這就是完全二叉樹。

*數組存儲表示

      當在數據處理過程中,二叉樹的大小和形態不發生劇烈的動態變化時,可以採用數組的方式來表示二叉樹的抽象數據結構類型。

         用數組方式存儲二叉樹結構,就是用一組連續的存儲單元存儲二叉樹的數據元素,爲了反映節點在二叉樹中的存儲位置及相互關係,必須適當安排節點的存儲

序。下面用數組來存儲一個完全二樹和一般二叉樹來。

                                                           

*鏈表存儲表示

        根據二叉樹定義,可以設計出二叉樹節點的構造。二叉樹的每個節點至少應該包括三個域:數據data、左子女節點指針和右子女節點指針rightChild,如圖(a)所示。這種鏈

表結構稱爲二叉樹鏈表,使用這種結構可以很方便地根據節點leftChild指針和rightChild指針找到他的左子女和右子女

                                                                                                  

*遍歷二叉樹的方法:

(1)前序遍歷(先根遍歷):根節點->左子樹->右子樹;【123456】

(2)中序遍歷:左子樹->根節點->右子樹;【324165】

(3)後序遍歷:左子樹->右子樹->根節點;【342651】

(4)層序遍歷:一層層節點依次遍歷。【125346】

當然遍歷二叉樹的方法不知這些,這只是比較簡單的幾種。

*代碼實現二叉樹

 #include<iostream>
 #include<stack>
 #include<queue>
 #include<assert.h>
 using namespace std;

//節點定義
template<class T>
struct BinaryTreeNode
{
   T _data;//數據
   BinaryTreeNode<T>* _left;//左孩子
   BinaryTreeNode<T>* _right;//右孩子
   BinaryTreeNode(const T& x)
           :_data(x)
           ,_left(NULL)
           ,_right(NULL)
         {}
};
//定義二叉樹
template<class T>

class BinaryTree
{
        typedef BinaryTreeNode<T> Node;
public:
       BinaryTree()
             :root(NULL)
              {}
       BinaryTree(T* a,size_t n,const T&invalid)
      {
             size_t index=0;
             _root=CreateTree(a,n,invalid,index);
      }
       Node* _copy(Node* root)
      {
             if(root==NULL)
                 return NULL;
            Node* newRoot=new Node(root->_data);
            newRoot->_left=_copy(root->_left);
            newRoot->_right=_copy(root->_right);
            return newRoot;
      }
       BinaryTree(const BinaryTree<T>& t)
     {
            _root=_copy(t._root);
      }
       BinaryTree<T>& operator=(BinaryTree<T> t)
       {
            swap(_root,t._root);
            return *this;
       }
        ~BinaryTree()
      {
            Destory(_root);
       }
         void Destory(Node* root)
       {
             if(root==NULL)
            return;
            Destory(root->_left);
            Destory(root->_right);
            delete root;
       }
       void PrevOrder()
       {
             _PrevOrder(_root);
            cout<<endl;
       }
        void InOrder()
       {
            _InOrder(_root);
            cout<<endl;
        }
         void PrevOrderNonR()
       {
             stack<Node*> s;
            Node* cur=_root;
             while(cur||!s.empty())
            {
                   while(cur)
                   {
                         cout<<cur->_data<<" ";
                         s.push(cur);
                         cur=cur->_left;
                  }
  //top從棧取出來表示這個節點的左子樹訪問過了
  //剩餘右子樹還沒有訪問,循環子問題訪問右數
                   Node* top=s.top();
                   s.pop();
  //子問題的方式訪問右數
                   cur=top->_right;
           }
               cout<<endl;
      }
     void InOrderNonR()//非遞歸實現先序遍歷
    {
          Node* cur=_root;
          stack<Node*> s;
          while(cur||!s.empty())
         {
              while(cur)
             {
                   s.push(cur);
                  cur=cur->_left;
             }
             Node* top=s.top;
            s.pop();
            cout<<top->_data<<" ";
  //子問題
            cur=top->_right;
         }
    }
    void PostOrderNonR()//非遞歸實現後序遍歷
    {
         Node* cur=_root;
         stack<Node*> s;
         Node* prev=NULL;
         while(cur||!s.empty())
        {
             while(cur)
            {
                 s.push(cur);
                 cur=cur->_left;
            }
           Node* front=s.top();
           if(front->_right==NULL||front->_right==prev)
           {
              cout<<front->_data<<" ";
              prev=front;
             s.pop();
           }
           else
           {
                cur=front->_right;
           }
      }
   cout<<endl;
   }
   void LevelOrder()//層序遍歷
  {
       queue<Node*> q;
       if(_root)
       {
            q.push(_root);
       }
      while(!q.empty())
     {
            Node* front=q.front();
            cout<<front->_data<<" ";
            if(front->_left)
            q.push(front->_left);
            if(front->_right)
            q.push(front->_right);
            q.pop();
      }
   cout<<endl;
  }
  size_t Size()//求樹的大小
   {
        return _Size(_root);
   }
    size_t LeafSize()//求葉子節點的個數
   {
        return _LeafSize(_root);
   }
   size_t GetkLeavel(size_t k)//求第K層葉子結點的個數
   {
        assert(k>0);
        return _GetkLeavel(_root,k);
    }
   Node* Find(const T& x)//查找某個節點
   {
         return _Find(_root,x);
   }
    size_t Depth()//求1樹的深度
   {
         return _Depth(_root);
   }
protected://真正實現的部分
       void _PrevOrder(Node* root)
       {
            if(root==NULL)
                return;
            cout<<root->_data;
            _PrevOrder(root->_left);
            _PrevOrder(root->_right);
      }
      void _InOrder(Node* root)
     {
           if(root==NULL)
               return;
           _InOrder(root->_left);
           cout<<root->_data<<" ";
           _InOrder(root->_right);
     }
     Node* CreateTree(T* a,size_t n,const T& invalid,size_t& index)
     {
            Node* root=NULL;
            if(index<n&&a[index]!=invalid)
            {
                   root=new Node(a[index]);
                   root->_left=CreateTree(a,n,invalid,++index);
                   root->_right=CreateTree(a,n,invalid,++index);
            }
            return root;
    }
    size_t _Size(Node* root)
    {
         if(root==NULL)
        {
            return 0;
         }
            return _Size(root->_left)+_Size(root->_right)+1;
    }
    size_t _LeafSize(Node* root)
    {
          if(root==NULL)
         {
               return 0;
          }
          if(root->_left==NULL||root->_right==NULL)
         {
              return 1;
         }
           return _LeafSize(root->_left)+_LeafSize(root->_right);
    }
    size_t _GetkLeavel(Node* root,size_t k)
   {
        if(root==NULL)
       {
            return 0;
       }
        if(k==1)
       {
            return 1;
       }
       return _GetkLeavel(root->_left,k-1)+_GetkLeavel(root->_right,k-1);
    }
    size_t _Depth(Node* root)
    {
           if(root==NULL)
                return 0;
           if(root->_left==NULL&&root->_right==NULL)
               return 1;
            size_t left=_Depth(root->_left);
            size_t right=_Depth(root->_right);
            return left>right?left+1:right+1;
   }
   Node* _Find(Node* root,const T&x)
  {
           if(root==NULL)
                 return NULL;
           if(root->_data==x)
                 return root;
           Node* ret=_Find(root->_left,x);
           if(ret)
                return ret;
             return _Find(root->_right,x);
   }
protected:
         Node* _root;
 };
 void TestBinaryTree()
 {
       int array[10]={1,2,3,'#','#',4,'#','#',5,6};
       BinaryTree<int> t1(array,sizeof(array)/sizeof(array[0]),'#');
       t1.PrevOrder();
       BinaryTree<int> t2(t1);
       t2.PrevOrderNonR();
       t1.PrevOrderNonR();
       t1.PostOrderNonR();
       t1.InOrder();
       t1.LevelOrder();
       cout<<"Size:"<<t1.Size()<<endl;
       cout<<"kLeavel:"<<t1.GetkLeavel(4)<<endl;
       cout<<"LeafSize:"<<t1.LeafSize()<<endl;
       cout<<"Depth:"<<t1.Depth()<<endl;
 }
 int main()
 {
       TestBinaryTree();
       return 0;
 }

發佈了53 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章