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

//轉(zhuǎn)載請(qǐng)標(biāo)明出處拉庵,原文地址:http://blog.csdn.net/hackbuteer1/article/details/6583988

#include

#include

#include

usingnamespacestd;

//二叉樹結(jié)點(diǎn)的描述

typedefstructBiTNode

{

chardata;

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

}BiTNode,*BiTree;

//按先序遍歷創(chuàng)建二叉樹

//BiTree?*CreateBiTree()?????//返回結(jié)點(diǎn)指針類型

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

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

{

charch;//要插入的數(shù)據(jù)

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

//cin>>ch;

if(ch=='#')

*root?=?NULL;

else

{

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

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

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

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

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

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

}

}

//前序遍歷的算法程序

voidPreOrder(BiTNode?*root)

{

if(root==NULL)

return;

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

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

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

}

//中序遍歷的算法程序

voidInOrder(BiTNode?*root)

{

if(root==NULL)

return;

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

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

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

}

//后序遍歷的算法程序

voidPostOrder(BiTNode?*root)

{

if(root==NULL)

return;

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

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

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

}

/*

二叉樹的非遞歸前序遍歷蜒车,前序遍歷思想:先讓根進(jìn)棧,只要棧不為空幔嗦,就可以做彈出操作酿愧,

每次彈出一個(gè)結(jié)點(diǎn),記得把它的左右結(jié)點(diǎn)都進(jìn)棧邀泉,記得右子樹先進(jìn)棧嬉挡,這樣可以保證右子樹在棧中總處于左子樹的下面。

*/

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)//?左子樹上的節(jié)點(diǎn)全部壓入到棧中

{

s.push(T);

cout<data<<"??";

T?=?T->lchild;

}

while(!s.empty())

{

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

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

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

{

cout<data<<"??";

s.push(temp);

temp?=?temp->lchild;

}

}

}

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

{

if(!T)

return;

BiTree?curr?=?T;//?指向當(dāng)前要檢查的節(jié)點(diǎn)

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;//?指向當(dāng)前要檢查的節(jié)點(diǎn)

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?;//?指向當(dāng)前要檢查的節(jié)點(diǎn)

BiTree?previsited?=?NULL;//?指向前一個(gè)被訪問的節(jié)點(diǎn)

while(curr?!=?NULL?||?!S.empty())//?椗痈郑空時(shí)結(jié)束

{

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

{

S.push(curr);

curr?=?curr->lchild;

}

curr?=?S.top();

//?當(dāng)前節(jié)點(diǎn)的右孩子如果為空或者已經(jīng)被訪問,則訪問當(dāng)前節(jié)點(diǎn)

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?;//?指向當(dāng)前要檢查的節(jié)點(diǎn)

s1.push(T);

while(!s1.empty())//?椧蚧眩空時(shí)結(jié)束

{

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];//定義隊(duì)列有十個(gè)空間

if(BT==NULL)

return;

intfront,rear;

front=rear=0;

queue[rear++]=BT;

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

{

cout<data<<"??";//輸出遍歷結(jié)果

if(queue[front]->lchild!=NULL)//將隊(duì)首結(jié)點(diǎn)的左孩子指針入隊(duì)列

{

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

rear++;//隊(duì)尾指針后移一位

}

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

{

queue[rear]=queue[front]->rchild;//將隊(duì)首結(jié)點(diǎn)的右孩子指針入隊(duì)列

rear++;//隊(duì)尾指針后移一位

}

front++;//對(duì)頭指針后移一位

}

}

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;//定義一個(gè)根結(jié)點(diǎn)

intflag=1,k;

printf("?????????????????????本程序?qū)崿F(xiàn)二叉樹的基本操作蓝角。\n");

printf("可以進(jìn)行建立二叉樹阱穗,遞歸先序、中序使鹅、后序遍歷,非遞歸先序昌抠、中序遍歷及非遞歸層序遍歷等操作患朱。\n");

while(flag)

{

printf("\n");

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

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

printf("|????????????????????????0.創(chuàng)建二叉樹??????????????????????????|\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.二叉樹的結(jié)點(diǎn)個(gè)數(shù)????????????????????|\n");

printf("|????????????????????????10.退出程序????????????????????????????|\n");

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

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

scanf("%d",&k);

switch(k)

{

case0:

printf("請(qǐng)建立二叉樹并輸入二叉樹的根節(jié)點(diǎn):");

CreateBiTree(&root);

break;

case1:

if(root)

{

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

PreOrder(root);

printf("\n");

}

else

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

break;

case2:

if(root)

{

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

InOrder(root);

printf("\n");

}

else

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

break;

case3:

if(root)

{

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

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("這棵二叉樹的結(jié)點(diǎn)個(gè)數(shù)為:%d\n",CountNode(root));

else

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

break;

default:

flag=0;

printf("程序運(yùn)行結(jié)束侥啤,按任意鍵退出!\n");

}

}

system("pause");

return0;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末茬故,一起剝皮案震驚了整個(gè)濱河市盖灸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌磺芭,老刑警劉巖赁炎,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異钾腺,居然都是意外死亡徙垫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門放棒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來松邪,“玉大人,你說我怎么就攤上這事哨查《阂郑” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵寒亥,是天一觀的道長(zhǎng)邮府。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么岭辣? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任柒室,我火速辦了婚禮,結(jié)果婚禮上仙辟,老公的妹妹穿的比我還像新娘。我一直安慰自己鳄梅,他們只是感情好叠国,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著戴尸,像睡著了一般粟焊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天项棠,我揣著相機(jī)與錄音悲雳,去河邊找鬼。 笑死香追,一個(gè)胖子當(dāng)著我的面吹牛合瓢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播透典,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼晴楔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了掷匠?” 一聲冷哼從身側(cè)響起滥崩,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎讹语,沒想到半個(gè)月后钙皮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顽决,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年短条,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才菠。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茸时,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赋访,到底是詐尸還是另有隱情可都,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布蚓耽,位于F島的核電站渠牲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏步悠。R本人自食惡果不足惜签杈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鼎兽。 院中可真熱鬧答姥,春花似錦、人聲如沸谚咬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽序宦。三九已至睁壁,卻和暖如春背苦,著一層夾襖步出監(jiān)牢的瞬間互捌,已是汗流浹背潘明。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秕噪,地道東北人钳降。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像腌巾,于是被迫代替她去往敵國和親遂填。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容