二叉樹的非遞迴(先序、中序、後序)遍曆

來源:互聯網
上載者:User

二叉樹的特點是每個結點至多隻有兩棵子樹,它是一種很重要的資料結構,從樹的特點我們可以利用遞迴很容易的實現它的建立以及遍曆操作,上一篇已經用遞迴的方法實現了二叉樹的先序、中序和後序的遍曆,下面的代碼是二叉樹的非遞迴遍曆的實現,三種遍曆方式都給出了兩種實現方法(注釋掉的即為第二種實現方法),注釋部分已經講原理寫出來了,由於自己語言群組織能力不是很好,原理就是從網上找來的,我自己是通過這些原理來實現的遍曆二叉樹,希望也能給看到代碼的人同樣協助。

/**@2012-12-14*二叉樹的非遞迴(先序、中序、後序)遍曆*/#include<iostream>using namespace std;typedef char TElemType;//二叉樹資料元素的類型typedef struct BitreeNode{TElemType TItem;struct BitreeNode *lchild;struct BitreeNode *rchild;}BitreeNode,*Bitree;typedef structSNode{         Bitree SItem;struct SNode *next;}SNode , * LinkStack;//初始化二叉樹int InitBitree(Bitree &T){T=(Bitree)malloc(sizeof(BitreeNode));if(!T)return 0;T->TItem='#';T->lchild=NULL;T->rchild=NULL;return 1;}//初始化棧int InitStack(LinkStack &S){S=(LinkStack)malloc(sizeof(SNode)); //通過malloc函數分配空間if (!S)return 0;               //如果分配失敗,則返回0S->next=NULL;return 1;}//判斷棧是否為空白int StackEmpty(LinkStack S){if (S!=NULL)                      //判斷棧是否存在{if (S->next==NULL){return 1;}}return 0;}//建立二叉樹int CreateBitree(Bitree &T){TElemType ch;ch=getchar();//測試字串abc##de#g##f###if(ch=='#')T=NULL;else{T=(Bitree)malloc(sizeof(BitreeNode));if(!T)return 0;else{T->TItem=ch;CreateBitree(T->lchild);CreateBitree(T->rchild);}}return 1;}//擷取棧頂元素int GetTop(LinkStack S,Bitree &e){LinkStack q=S;if (S!=NULL) //判斷棧是否存在{if (q->next!=NULL)//判斷棧是否為空白{while (q->next!=NULL){q=q->next;}e=q->SItem;return 1;}}return 0;             //如果不能得到資料元素,則返回0(false)}//壓棧函數int Push(LinkStack &S,Bitree e){LinkStack q=S;LinkStack m=(LinkStack)malloc(sizeof(SNode)); //通過malloc函數分配空間if (S!=NULL){while (q->next!=NULL){q=q->next;}m->SItem=e;m->next=NULL;q->next=m;}return 0;}//出棧函數int Pop(LinkStack &S,Bitree &e){LinkStack q=S;if (S!=NULL){if (q->next!=NULL)    //若棧不是空的{while (q->next->next!=NULL){q=q->next;}e=q->next->SItem;q->next=NULL;return 1;}}return 0;}//遍曆訪問函數int Visit(TElemType e){if(e!=NULL){cout<<e<<" ";return 1;}elsereturn 0;}/*先序遍曆二叉樹根->左->右;1)訪問結點P,並將結點P入棧;2)判斷結點P的左孩子是否為空白,若為空白,則取棧頂結點並進行出棧操作,並將棧頂結點的右孩子置為當前的結點P,迴圈至1);  若不為空白,則將P的左孩子置為當前的結點P;3)直到P為NULL並且棧為空白,則遍曆結束。*/int PreOrederTraverse(Bitree &T,int(*Visit)(TElemType)){/*LinkStack S;Bitree p=T;InitStack(S);Push(S,T);while (p || !StackEmpty(S)){while (p!=NULL){Visit(p->TItem);Push(S,p);p=p->lchild;}if(!StackEmpty(S)){GetTop(S,p);Pop(S,p);p=p->rchild;}}*/LinkStack S;Bitree p=T;InitStack(S);Push(S,T);while (!StackEmpty(S)){while (GetTop(S,p) && p){if(!Visit(p->TItem))return 0;Push(S,p->lchild);//向左走到盡頭}Pop(S,p);//null 指標退棧if(!StackEmpty(S)){//訪問節點,向右一步Pop(S,p);Push(S,p->rchild);}}return 0;}/**中遍曆二叉樹:左->根->右1)若其左孩子不為空白,則將P入棧並將P的左孩子置為當前的P,然後對當前結點P再進行相同的處理;2)若其左孩子為空白,則取棧頂元素並進行出棧操作,訪問該棧頂結點,然後將當前的P置為棧頂結點的右孩子;3)直到P為NULL並且棧為空白則遍曆結束*/int InOrderTraverse(Bitree &T,int(*Visit)(TElemType)){/*LinkStack S;Bitree p=T;InitStack(S);Push(S,T);//根指標進棧while (p || !StackEmpty(S)){if(p){Push(S,p);p=p->lchild;//根指標進棧,遍曆左子樹}else//根指標退棧,訪問根結點,遍曆右子樹{Pop(S,p);if(!Visit(p->TItem))return 0;p=p->rchild;}}*/LinkStack S;Bitree p=T;InitStack(S);Push(S,T);//根指標進棧while (!StackEmpty(S)){while (GetTop(S,p) && p){Push(S,p->lchild);//向左走到盡頭}Pop(S,p);//null 指標退棧if(!StackEmpty(S)){//訪問節點,向右一步Pop(S,p);if(!Visit(p->TItem))return 0;Push(S,p->rchild);}}return 1;}/**後序遍曆二叉樹:左->右->根1)對於任一結點P,先將其入棧。2)如果P不存在左孩子和右孩子,或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被訪問過了,則可以直接存取該結點。3)若非上述兩種情況,則將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問。  左孩子和右孩子都在根結點前面被訪問。*/int PostOrderTraverse(Bitree &T,int(*Visit)(TElemType)){/*Bitree q=T;LinkStack S;InitStack(S);while (T || !StackEmpty(S)){if (T){Push(S, T);T=T->lchild;}else{GetTop(S, T);if (T->rchild==NULL || T->rchild==q){Visit(T->TItem);Pop(S, T);q=T;T=NULL;}else{T=T->rchild;}} }*/LinkStack S;Bitree cur;//當前結點Bitree pre=NULL;//前一次訪問的結點InitStack(S);Push(S,T);//根指標進棧    while(!StackEmpty(S))    {        GetTop(S,cur);        if((cur->lchild==NULL&&cur->rchild==NULL)||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))        {//如果當前結點沒有孩子結點或者孩子節點都已被訪問過 Visit(cur->TItem); Pop(S,cur);            pre=cur;         }        else//將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問        {            if(cur->rchild!=NULL)               Push(S,cur->rchild);            if(cur->lchild!=NULL)                   Push(S,cur->lchild);        }    } return 0;}int main(){Bitree T;InitBitree(T);CreateBitree(T);cout<<"先序遍曆:";PreOrederTraverse(T,Visit);cout<<endl;cout<<"中序遍曆:";InOrderTraverse(T,Visit);cout<<endl;cout<<"後序遍曆:";PostOrderTraverse(T,Visit);cout<<endl;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.