二叉樹遍歷【很好的文章】

//轉載請標明出處,原文地址:http://blog.csdn.net/hackbuteer1/article/details/6583988

#include

#include

#include

usingnamespacestd;

//二叉樹結點的描述

typedefstructBiTNode

{

chardata;

structBiTNode?*lchild,?*rchild;//左右孩子

}BiTNode,*BiTree;

//按先序遍歷創建二叉樹

//BiTree?*CreateBiTree()?????//返回結點指針類型

//void?CreateBiTree(BiTree?&root)??????//引用類型的參數

voidCreateBiTree(BiTNode?**root)//二級指針作為函數參數

{

charch;//要插入的數據

scanf("\n%c",?&ch);

//cin>>ch;

if(ch=='#')

*root?=?NULL;

else

{

*root?=?(BiTNode?*)malloc(sizeof(BiTNode));

(*root)->data?=?ch;

printf("請輸入%c的左孩子:",ch);

CreateBiTree(&((*root)->lchild));

printf("請輸入%c的右孩子:",ch);

CreateBiTree(&((*root)->rchild));

}

}

//前序遍歷的算法程序

voidPreOrder(BiTNode?*root)

{

if(root==NULL)

return;

printf("%c?",?root->data);//輸出數據

PreOrder(root->lchild);//遞歸調用,前序遍歷左子樹

PreOrder(root->rchild);//遞歸調用,前序遍歷右子樹

}

//中序遍歷的算法程序

voidInOrder(BiTNode?*root)

{

if(root==NULL)

return;

InOrder(root->lchild);//遞歸調用,前序遍歷左子樹

printf("%c?",?root->data);//輸出數據

InOrder(root->rchild);//遞歸調用,前序遍歷右子樹

}

//后序遍歷的算法程序

voidPostOrder(BiTNode?*root)

{

if(root==NULL)

return;

PostOrder(root->lchild);//遞歸調用,前序遍歷左子樹

PostOrder(root->rchild);//遞歸調用,前序遍歷右子樹

printf("%c?",?root->data);//輸出數據

}

/*

二叉樹的非遞歸前序遍歷,前序遍歷思想:先讓根進棧,只要棧不為空,就可以做彈出操作,

每次彈出一個結點,記得把它的左右結點都進棧,記得右子樹先進棧,這樣可以保證右子樹在棧中總處于左子樹的下面。

*/

voidPreOrder_Nonrecursive(BiTree?T)//先序遍歷的非遞歸

{

if(!T)

return;

stack?s;

s.push(T);

while(!s.empty())

{

BiTree?temp?=?s.top();

cout<data<<"?";

s.pop();

if(temp->rchild)

s.push(temp->rchild);

if(temp->lchild)

s.push(temp->lchild);

}

}

voidPreOrder_Nonrecursive1(BiTree?T)//先序遍歷的非遞歸

{

if(!T)

return;

stack?s;

BiTree?curr?=?T;

while(curr?!=?NULL?||?!s.empty())

{

while(curr?!=?NULL)

{

cout<data<<"??";

s.push(curr);

curr?=?curr->lchild;

}

if(!s.empty())

{

curr?=?s.top();

s.pop();

curr?=?curr->rchild;

}

}

}

voidPreOrder_Nonrecursive2(BiTree?T)//先序遍歷的非遞歸

{

if(!T)

return;

stack?s;

while(T)//?左子樹上的節點全部壓入到棧中

{

s.push(T);

cout<data<<"??";

T?=?T->lchild;

}

while(!s.empty())

{

BiTree?temp?=?s.top()->rchild;//?棧頂元素的右子樹

s.pop();//?彈出棧頂元素

while(temp)//?棧頂元素存在右子樹,則對右子樹同樣遍歷到最下方

{

cout<data<<"??";

s.push(temp);

temp?=?temp->lchild;

}

}

}

voidInOrderTraverse1(BiTree?T)//?中序遍歷的非遞歸

{

if(!T)

return;

BiTree?curr?=?T;//?指向當前要檢查的節點

stack?s;

while(curr?!=?NULL?||?!s.empty())

{

while(curr?!=?NULL)

{

s.push(curr);

curr?=?curr->lchild;

}//while

if(!s.empty())

{

curr?=?s.top();

s.pop();

cout<data<<"??";

curr?=?curr->rchild;

}

}

}

voidInOrderTraverse(BiTree?T)//?中序遍歷的非遞歸

{

if(!T)

return;

stack?s;

BiTree?curr?=?T->lchild;//?指向當前要檢查的節點

s.push(T);

while(curr?!=?NULL?||?!s.empty())

{

while(curr?!=?NULL)//?一直向左走

{

s.push(curr);

curr?=?curr->lchild;

}

curr?=?s.top();

s.pop();

cout<data<<"??";

curr?=?curr->rchild;

}

}

voidPostOrder_Nonrecursive1(BiTree?T)//?后序遍歷的非遞歸

{

stack?S;

BiTree?curr?=?T?;//?指向當前要檢查的節點

BiTree?previsited?=?NULL;//?指向前一個被訪問的節點

while(curr?!=?NULL?||?!S.empty())//?棧空時結束

{

while(curr?!=?NULL)//?一直向左走直到為空

{

S.push(curr);

curr?=?curr->lchild;

}

curr?=?S.top();

//?當前節點的右孩子如果為空或者已經被訪問,則訪問當前節點

if(curr->rchild?==?NULL?||?curr->rchild?==?previsited)

{

cout<data<<"??";

previsited?=?curr;

S.pop();

curr?=?NULL;

}

else

curr?=?curr->rchild;//?否則訪問右孩子

}

}

voidPostOrder_Nonrecursive(BiTree?T)//?后序遍歷的非遞歸?????雙棧法

{

stack?s1?,?s2;

BiTree?curr?;//?指向當前要檢查的節點

s1.push(T);

while(!s1.empty())//?棧空時結束

{

curr?=?s1.top();

s1.pop();

s2.push(curr);

if(curr->lchild)

s1.push(curr->lchild);

if(curr->rchild)

s1.push(curr->rchild);

}

while(!s2.empty())

{

printf("%c?",?s2.top()->data);

s2.pop();

}

}

intvisit(BiTree?T)

{

if(T)

{

printf("%c?",T->data);

return1;

}

else

return0;

}

voidLeverTraverse(BiTree?T)//方法一、非遞歸層次遍歷二叉樹

{

queue??Q;

BiTree?p;

p?=?T;

if(visit(p)==1)

Q.push(p);

while(!Q.empty())

{

p?=?Q.front();

Q.pop();

if(visit(p->lchild)?==?1)

Q.push(p->lchild);

if(visit(p->rchild)?==?1)

Q.push(p->rchild);

}

}

voidLevelOrder(BiTree?BT)//方法二、非遞歸層次遍歷二叉樹

{

BiTNode?*queue[10];//定義隊列有十個空間

if(BT==NULL)

return;

intfront,rear;

front=rear=0;

queue[rear++]=BT;

while(front!=rear)//如果隊尾指針不等于對頭指針時

{

cout<data<<"??";//輸出遍歷結果

if(queue[front]->lchild!=NULL)//將隊首結點的左孩子指針入隊列

{

queue[rear]=queue[front]->lchild;

rear++;//隊尾指針后移一位

}

if(queue[front]->rchild!=NULL)

{

queue[rear]=queue[front]->rchild;//將隊首結點的右孩子指針入隊列

rear++;//隊尾指針后移一位

}

front++;//對頭指針后移一位

}

}

intdepth(BiTNode?*T)//樹的深度

{

if(!T)

return0;

intd1,d2;

d1=depth(T->lchild);

d2=depth(T->rchild);

return(d1>d2?d1:d2)+1;

//return?(depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1;

}

intCountNode(BiTNode?*T)

{

if(T?==?NULL)

return0;

return1+CountNode(T->lchild)+CountNode(T->rchild);

}

intmain(void)

{

BiTNode?*root=NULL;//定義一個根結點

intflag=1,k;

printf("?????????????????????本程序實現二叉樹的基本操作。\n");

printf("可以進行建立二叉樹,遞歸先序、中序、后序遍歷,非遞歸先序、中序遍歷及非遞歸層序遍歷等操作。\n");

while(flag)

{

printf("\n");

printf("|--------------------------------------------------------------|\n");

printf("|????????????????????二叉樹的基本操作如下:?????????????????????|\n");

printf("|????????????????????????0.創建二叉樹??????????????????????????|\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("|--------------------------------------------------------------|\n");

printf("????????????????????????請選擇功能:");

scanf("%d",&k);

switch(k)

{

case0:

printf("請建立二叉樹并輸入二叉樹的根節點:");

CreateBiTree(&root);

break;

case1:

if(root)

{

printf("遞歸先序遍歷二叉樹的結果為:");

PreOrder(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case2:

if(root)

{

printf("遞歸中序遍歷二叉樹的結果為:");

InOrder(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case3:

if(root)

{

printf("遞歸后序遍歷二叉樹的結果為:");

PostOrder(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case4:

if(root)

{

printf("非遞歸先序遍歷二叉樹:");

PreOrder_Nonrecursive1(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case5:

if(root)

{

printf("非遞歸中序遍歷二叉樹:");

InOrderTraverse1(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case6:

if(root)

{

printf("非遞歸后序遍歷二叉樹:");

PostOrder_Nonrecursive(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case7:

if(root)

{

printf("非遞歸層序遍歷二叉樹:");

//LeverTraverse(root);

LevelOrder(root);

printf("\n");

}

else

printf("??????????二叉樹為空!\n");

break;

case8:

if(root)

printf("這棵二叉樹的深度為:%d\n",depth(root));

else

printf("??????????二叉樹為空!\n");

break;

case9:

if(root)

printf("這棵二叉樹的結點個數為:%d\n",CountNode(root));

else

printf("??????????二叉樹為空!\n");

break;

default:

flag=0;

printf("程序運行結束,按任意鍵退出!\n");

}

}

system("pause");

return0;

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容