【100題】第四十二題 二叉樹的非遞迴遍曆

來源:互聯網
上載者:User

一,前序走訪非遞迴:

       根據前序走訪訪問的順序,優先訪問根結點,然後再分別訪問左孩子和右孩子。即對於任一結點,其可看做是根結點,因此可以直接存取,訪問完之後,若其左孩子不為空白,按相同規則訪問它的左子樹;當訪問其左子樹時,再訪問它的右子樹。因此其處理過程如下:

        對於任一結點P:

           1)訪問結點P,並將結點P入棧;

           2)判斷結點P的左孩子是否為空白,若為空白,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點P,迴圈至1);若不為空白,則將P的左孩子置為當前的結點P;

           3)直到P為NULL並且棧為空白,則遍曆結束。

void preOrder2(node *root)     //非遞迴前序走訪

{

    stack<node*> s;

    node *p=root;

    while(p!=NULL||!s.empty())

    {

        while(p!=NULL)//向左遍曆直到葉子

        {

            cout<<p->data<<" ";

            s.push(p);

            p=p->lchild;

        }

        if(!s.empty())

        {

            p=s.top();

            s.pop();

            p=p->rchild;

        }

    }

    cout<<endl;

}

二,中序遍曆非遞迴

 

      根據中序遍曆的順序,對於任一結點,優先訪問其左孩子,而左孩子結點又可以看做一根結點,然後繼續訪問其左孩子結點,直到遇到左孩子結點為空白的結點才進行訪問,然後按相同的規則訪問其右子樹。因此其處理過程如下:

      對於任一結點P,

           1)若其左孩子不為空白,則將P入棧並將P的左孩子置為當前的P,然後對當前結點P再進行相同的處理;

           2)若其左孩子為空白,則取棧頂元素並進行出棧操作,訪問該棧頂結點,然後將當前的P置為棧頂結點的右孩子;

           3)直到P為NULL並且棧為空白則遍曆結束

void inOrder2(node *root)      //非遞迴中序遍曆

{

    stack<node*> s;

    node *p=root;

    while(p!=NULL||!s.empty())

    {

        while(p!=NULL)//記錄訪問過的根節點

        {

            s.push(p);

            p=p->lchild;

        }

        if(!s.empty())

        {

            p=s.top();

            cout<<p->data<<" "; //訪問棧頂

            s.pop();

            p=p->rchild;  //將當前訪問的元素的右孩子入棧

        }

    }   

}

 

            要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點P,先將其入棧。如果P不存在左孩子和右孩子,則可以直接存取它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則同樣可以直接存取該結點。若非上述兩種情況,則將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。

 

void postOrder3(node *root)     //非遞迴後序遍曆

{

    stack<node*> s;

    node *cur;                      //當前結點

    node *pre=NULL;                 //前一次訪問的結點

    s.push(root);

    while(!s.empty())

    {

        cur=s.top();

        if((cur->lchild==NULL&&cur->rchild==NULL)||

           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))

          {

            cout<<cur->data<<" ";  //如果當前結點沒有孩子結點或者孩子節點都已被訪問過

              s.pop();

            pre=cur;

         }

        else

        {

            if(cur->rchild!=NULL)

                s.push(cur->rchild);

            if(cur->lchild!=NULL)   

                s.push(cur->lchild);

        }

    }   

}

 

綜合程式附錄

#include "stdio.h"#include "stdlib.h" #include "stack.h"int count;//統計葉子節點個數 struct node{int data;//二叉樹的節點值node *lchild,*rchild;//左右孩子節點 };/*不知道為什麼 建立的時候需要傳回值才 建立有效*/node *createTree(){node *root;int data;printf("input data:");scanf("%d",&data);//printf("output data:%d\n",data);if(data==0)  root=NULL;    else/*根左右 前序建立二叉樹*/    {    root=(node*)malloc(sizeof(node));    root->data=data;    root->lchild=createTree();    root->rchild=createTree();    }return root;} void preOrder(node *root){if(root==NULL)        return;else//不是空{printf("%d\n",root->data);preOrder(root->lchild);preOrder(root->rchild); } }void inOrder(node *root){if(root==NULL)        return;else//不是空{inOrder(root->lchild);printf("%d\n",root->data);inOrder(root->rchild); } }void postOrder(node *root){if(root==NULL)        return;else//不是空{postOrder(root->lchild);postOrder(root->rchild);printf("%d\n",root->data); } }void  CountLeaves(node *root){if(root==NULL)        return;else//不是空{if(root->lchild==NULL&&root->rchild==NULL)     count++;CountLeaves(root->lchild);CountLeaves(root->rchild); } } int deepLength(node *root){int deep1,deep2;if(root==NULL)    return 0;    else    {    deep1=deepLength(root->lchild);    deep2=deepLength(root->rchild);    if(deep1>deep2)         return deep1+1;//這個地方一定是返回+1         else             return deep2+1;    }}void  CountNodes(node *root){if(root==NULL)        return;else//不是空{        count++;CountNodes(root->lchild);CountNodes(root->rchild); } } void exchange(node *root){if(root==NULL)   return;    else    {    exchange(root->lchild);    exchange(root->rchild);    node *temp=root->lchild;    root->lchild=root->rchild;    root->rchild=temp;        }}void search(node *root,int x){if(root==NULL)    return ;    else       {         if(root->data==x)            {            count++;              printf("has\n");            }               search(root->lchild,x);      search(root->rchild,x);       }}void preOrder2(node *root)     //非遞迴前序走訪 {    stack<node*> s;    node *p=root;    while(p!=NULL||!s.empty())    {        while(p!=NULL)//向左遍曆 直到葉子         {            cout<<p->data<<" ";            s.push(p);            p=p->lchild;        }        if(!s.empty())        {            p=s.top();            s.pop();            p=p->rchild;        }    }    cout<<endl; }void inOrder2(node *root)      //非遞迴中序遍曆{    stack<node*> s;    node *p=root;    while(p!=NULL||!s.empty())    {        while(p!=NULL)        {            s.push(p);            p=p->lchild;        }        if(!s.empty())        {            p=s.top();            cout<<p->data<<" ";            s.pop();            p=p->rchild;        }    }    }void postOrder3(node *root)     //非遞迴後序遍曆{    stack<node*> s;    node *cur;                      //當前結點     node *pre=NULL;                 //前一次訪問的結點     s.push(root);    while(!s.empty())    {        cur=s.top();        if((cur->lchild==NULL&&cur->rchild==NULL)||           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))        {            cout<<cur->data<<" ";  //如果當前結點沒有孩子結點或者孩子節點都已被訪問過               s.pop();            pre=cur;         }        else        {            if(cur->rchild!=NULL)                s.push(cur->rchild);            if(cur->lchild!=NULL)                    s.push(cur->lchild);        }    }    }/*一定要記住直接輸入1 2 3 0 0 0 0 建立的是 左二叉樹 平衡的應該是 1 2 0 0 3 0 0*/int main(){node *root;//=(node*)malloc(sizeof(node));//這裡不要初始化了 因為建立的時候要初始化 printf("             Please select what you  want do\n");printf("----------------------------------------------\n");printf("    1.前序建立二叉樹\n");printf("    2.遞迴前序走訪二叉樹\n");printf("    3.遞迴中序遍曆二叉樹\n");printf("    4.遞迴後序遍曆二叉樹\n");printf("    5.求分葉節點個數\n");printf("    6.求樹的高度\n");printf("    7.求二叉樹節點個數\n");printf("    8.交換左右子樹\n");printf("    9.尋找有無某個節點\n");printf("    10.非遞迴前序走訪二叉樹\n");printf("    11.非遞迴前序走訪二叉樹\n");printf("    12.非遞迴前序走訪二叉樹\n");printf("    15.退出\n"); int i;while(true){scanf("%d",&i);     switch(i)    {    case 1: root=createTree();        printf("create tree is finished please select what you want do next:\n");break;    case 2:printf("Now outPut data in PreOrder:\n");                preOrder(root);                printf("output is over please select again\n");break;    case 3: printf("Now outPut data in inOrder:\n");                inOrder(root);printf("output is over please select again\n");break;    case 4: printf("Now outPut data in postOrder:\n");                postOrder(root);printf("output is over please select again\n");break;    case 5: count=0;            CountLeaves(root);                    printf("The leaves's count is:%d\n",count);printf("output is over please select again\n");break;//葉子節點的個數     case 6: int deep=deepLength(root);                    printf("The tree's deepLength is:%d\n",deep);printf("output is over please select again\n");break;    case 7: count=0;            CountNodes(root);                    printf("The leaves's count is:%d\n",count);printf("output is over\n");         break;//求二叉樹節點個數     case 8: exchange(root);        break;            case 9: printf("please input what you want search\n");                    int x;                    scanf("%d",&x);                    count=0;                    search(root,x);if(count!=0)                       {      printf("The tree has this root\n");                          printf("output is over please select again\n");                       }                    else                       {      printf("The tree not has this root\n");      printf("output is over please select again\n");                       }        break;            case 10:printf("Now outPut data in PreOrder:\n");                preOrder2(root);                printf("output is over please select again\n");break;            case 11:printf("Now outPut data in PreOrder:\n");                inOrder2(root);                printf("output is over please select again\n");break;            case 12:printf("Now outPut data in PreOrder:\n");                postOrder3(root);                printf("output is over please select again\n");break;                    case 15: exit(0); break;//包含在stdlib.h當中         }   } return 0;}

 
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.