二叉樹----節點個數、高度、遞歸和非遞歸遍歷、按層遍歷

轉自:http://blog.csdn.net/dazhong159/article/details/7862774

1、二叉樹的數據結構(數據域+指向左/右孩子節點的指針)

    typedef struct tree
    {
         int data;
         struct tree *left;
         struct tree *right;
    }Tree,*pTree;

2、創建二叉查找樹

[html] view plaincopy
  1. //創建二叉樹(二叉查找樹),返回根節點  
  2. pTree createTree(int *data,int len)  
  3. {  
  4.     if (len<1)  
  5.     {  
  6.         cout<<"創建的樹爲空樹!"<<endl;  
  7.         return NULL;  
  8.     }  
  9.     pTree root=(pTree)malloc(sizeof(Tree));  
  10.     root->data=data[0];  
  11.     root->left=NULL;  
  12.     root->right=NULL;  
  13.   
  14.   
  15.     pTree current,back;  
  16.     for (int i=1;i<len;i++)  
  17.     {  
  18.         pTree newNode=(pTree)malloc(sizeof(Tree));  
  19.         newNode->data=data[i];  
  20.         newNode->left=NULL;  
  21.         newNode->right=NULL;  
  22.   
  23.         current=root;//每次插入新的節點時,current都指向root  
  24.         while(current!=NULL)  
  25.         {  
  26.             back=current;  
  27.             if (current->data>data[i])  
  28.                 current=current->left;  
  29.             else  
  30.                 current=current->right;  
  31.         }  
  32.   
  33.         if(back->data>data[i])  
  34.             back->left=newNode;  
  35.         else  
  36.             back->right=newNode;  
  37.     }  
  38.   
  39.     return root;  
  40. }  

3、二叉樹節點個數(遞歸法)

[html] view plaincopy
  1. //遞歸求樹的節點個數(左子樹節點個數+右子樹節點個數+根節點個數)  
  2. int getNode(pTree root)  
  3. {  
  4.     if (root==NULL)  
  5.         return 0;  
  6.     else if (root->left==NULL&&root->right==NULL)  
  7.         return 1;  
  8.     else  
  9.         return getNode(root->left)+getNode(root->right)+1;  
  10. }  

4、二叉樹的高度(遞歸法)

[html] view plaincopy
  1. //遞歸求樹的高度(左子樹和右子樹高度中的較大的值+根節點高度1)  
  2. int getHeight(pTree root)  
  3. {  
  4.     if (root==NULL)  
  5.         return 0;  
  6.       
  7.     int lh=getHeight(root->left);  
  8.     int rh=getHeight(root->right);  
  9.       
  10.     return lh>rh ? lh+1:rh+1;  
  11. }  

5、遞歸遍歷二叉樹

[html] view plaincopy
  1. //遞歸進行前序遍歷  
  2. void preTraverse(pTree root)  
  3. {  
  4.     if (root!=NULL)  
  5.     {  
  6.         cout<<root->data<<" ";  
  7.         preTraverse(root->left);  
  8.         preTraverse(root->right);  
  9.     }  
  10. }  
  11.   
  12. //遞歸進行中序遍歷  
  13. void midTraverse(pTree root)  
  14. {  
  15.     if (root!=NULL)  
  16.     {  
  17.         midTraverse(root->left);  
  18.         cout<<root->data<<" ";  
  19.         midTraverse(root->right);  
  20.     }  
  21. }  
  22.   
  23. //遞歸進行後序遍歷  
  24. void postTraverse(pTree root)  
  25. {  
  26.     if (root!=NULL)  
  27.     {  
  28.         postTraverse(root->left);  
  29.         postTraverse(root->right);  
  30.         cout<<root->data<<" ";  
  31.     }  
  32. }  

6、非遞歸遍歷二叉樹

[html] view plaincopy
  1. /**************************************************************************  
  2.  * 利用棧進行前序遍歷  
  3.  * 1、從根節點開始,遍歷左子樹,輸出父節點的內容,並將父節點入棧(這裏用數組代替)  
  4.  * 2、遍歷遇到節點爲NULL時,取出棧頂元素,得到其右孩子節點  
  5.  * 3、右孩子節點不爲空時,此時將該右節點看作是根節點,重複1、2操作  
  6.  * 4、右孩子節點爲空時,繼續出棧,得到右孩子節點,重複3、4操作  
  7. **************************************************************************/  
  8. void prePrint(pTree root)  
  9. {  
  10.     pTree p=root;  
  11.     int height=getHeight(root);  
  12.     pTree *sk=new pTree[height+1];  
  13.     int cnt=0;  
  14.     while(p!=NULL||cnt!=0)  
  15.     {  
  16.         if (p!=NULL)    
  17.         {  
  18.             cout<<p->data<<" ";  
  19.             sk[cnt++]=p;  
  20.             p=p->left;  
  21.         }   
  22.         else  
  23.         {  
  24.             p=sk[--cnt];  
  25.             p=p->right;  
  26.         }  
  27.     }  
  28.     delete []sk;  
  29. }  
  30.   
  31. /****************************************************************************  
  32.  * 利用棧進行中序遍歷  
  33.  * 1、從根節點開始,遍歷左子樹,將父節點入棧(這裏用數組代替)  
  34.  * 2、遍歷遇到節點爲NULL時,取出棧頂元素,輸出節點內容,得到其右孩子節點  
  35.  * 3、右孩子節點不爲空時,此時將該右節點看作是根節點,重複1、2操作  
  36.  * 4、右孩子節點爲空時,繼續出棧,重複3、4操作  
  37. ****************************************************************************/  
  38. void midPrint(pTree root)  
  39. {  
  40.     pTree p=root;  
  41.     int height=getHeight(root);  
  42.     pTree *sk=new pTree[height+1];  
  43.     int cnt=0;  
  44.     while(p!=NULL||cnt!=0)  
  45.     {  
  46.         if (p!=NULL)  
  47.         {  
  48.             sk[cnt++]=p;  
  49.             p=p->left;  
  50.         }  
  51.         else  
  52.         {  
  53.             p=sk[--cnt];  
  54.             cout<<p->data<<" ";  
  55.             p=p->right;  
  56.         }  
  57.     }  
  58.     delete []sk;  
  59. }  
  60.   
  61. /**********************************************************************  
  62.  * 利用棧後序遍歷  
  63.  * 1、首先創建一種新的數據結構,包含原來的數據結構和isFirst標誌()  
  64.  * 2、從根節點開始,入棧,將isFirst置爲1,訪問左子樹  
  65.  * 3、遇到節點爲NULL時,如果isFirst==1,訪問棧頂元素,得到該節點的右孩子  
  66.  * 4、該節點的右孩子爲NULL時,出棧,訪問該節點,然後將該節點置爲NULL,使下次循環必定會進入第3步  
  67.  * 5、該節點的右孩子不爲NULL時,將該右孩子當作根節點,重複2、3  
  68. **********************************************************************/  
  69. void postPrint(pTree root)  
  70. {  
  71.     int height=getHeight(root);  
  72.     struct TPostTree    //節點新的數據結構  
  73.     {  
  74.         pTree node;  
  75.         int isFirst;  
  76.     };  
  77.     TPostTree *sk=new TPostTree[height+1];  
  78.     int cnt=0;  
  79.   
  80.     pTree p=root;  
  81.     while(p!=NULL||cnt!=0)  
  82.     {  
  83.         if (p!=NULL)  //左  
  84.         {  
  85.             sk[++cnt].node=p;  
  86.             sk[cnt].isFirst=1;  
  87.             p=p->left;  
  88.         }  
  89.         else if (sk[cnt].isFirst)   //右  
  90.         {  
  91.             sk[cnt].isFirst=0;  
  92.             p=sk[cnt].node->right;  //根據sk保存的找到右節點  
  93.         }   
  94.         else        //根節點  
  95.         {  
  96.             p=sk[cnt--].node;  
  97.             cout<<p->data<<" ";  
  98.             p=NULL;                 //保證下次循環必定進入if的else分支  
  99.         }  
  100.     }  
  101.     delete []sk;  
  102. }  

7、按層遍歷二叉樹

[html] view plaincopy
  1. /***************************************************************************  
  2.  * 按層遍歷  
  3.  * 1、訪問根節點,將根節點進隊  
  4.  * 2、取出隊列的第一個元素,訪問該元素,並將取出的該元素節點的左右孩子節點(不爲NULL)進隊  
  5.  * 3、循環進行第二步,直至隊列爲空  
  6.  * 4、下面的代碼用數組替換了隊列  
  7. ***************************************************************************/  
  8. void BTraverse(pTree root)  
  9. {  
  10.     int n=getNode(root);  
  11.     pTree *sk=new pTree[n],p;  
  12.     int front=0,rear=0;  
  13.     sk[front]=root;  
  14.     while(front!=n)  
  15.     {  
  16.         p=sk[front];  
  17.         cout<<p->data<<" ";  
  18.         if (p->left!=NULL)  
  19.         {  
  20.             sk[rear+1]=p->left;  
  21.             rear++;  
  22.         }  
  23.         if (p->right!=NULL)  
  24.         {  
  25.             sk[rear+1]=p->right;  
  26.             rear++;  
  27.         }  
  28.         front++;  
  29.     }  
  30.   
  31.     cout<<endl;  
  32.     delete []sk;  

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