C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)先序、中序、后序及層次四種遍歷
一、圖示展示
(1)先序遍歷
先序遍歷可以想象為,一個(gè)小人從一棵二叉樹(shù)根節(jié)點(diǎn)為起點(diǎn),沿著二叉樹(shù)外沿,逆時(shí)針走一圈回到根節(jié)點(diǎn),路上遇到的元素順序,就是先序遍歷的結(jié)果
先序遍歷結(jié)果為:A B D H I E J C F K G
動(dòng)畫(huà)演示:
記住小人沿著外圍跑一圈(直到跑回根節(jié)點(diǎn)),多看幾次動(dòng)圖便能理解
(2)中序遍歷
中序遍歷可以看成,二叉樹(shù)每個(gè)節(jié)點(diǎn),垂直方向投影下來(lái)(可以理解為每個(gè)節(jié)點(diǎn)從最左邊開(kāi)始垂直掉到地上),然后從左往右數(shù),得出的結(jié)果便是中序遍歷的結(jié)果
中遍歷結(jié)果為:H D I B E J A F K C G
動(dòng)畫(huà)展示:
記住,中序遍歷就是從最左邊開(kāi)始,把每個(gè)節(jié)點(diǎn)垂直投影到同一直線上,然后從左往右讀值就可以了,多看幾遍動(dòng)圖就理解了
(3)后序遍歷
后序遍歷就像是剪葡萄,我們要把一串葡萄剪成一顆一顆的。
還記得我上面提到先序遍歷繞圈的路線么?(不記得翻上面理解)
就是圍著樹(shù)的外圍繞一圈,如果發(fā)現(xiàn)一剪刀就能剪下的葡萄(必須是一顆葡萄)(也就是葡萄要一個(gè)一個(gè)掉下來(lái),不能一口氣掉超過(guò)1個(gè)這樣),就把它剪下來(lái),組成的就是后序遍歷了。
后序遍歷中,根節(jié)點(diǎn)默認(rèn)最后面
后序遍歷結(jié)果:H I D J E B K F G C A
動(dòng)畫(huà)展示:
(4)層次遍歷
層次遍歷很好理解,就是從根節(jié)點(diǎn)開(kāi)始,一層一層,從上到下,每層從左到右,依次寫(xiě)值就可以了
層次遍歷結(jié)果:A B C D E F G H I J K
解釋外圈跑的意思:
繞著外圍跑一整圈的真正含義是:遍歷所有結(jié)點(diǎn)時(shí),都先往左孩子走,再往右孩子走。
(5)口訣
先序遍歷: 先根 再左 再右
中序遍歷: 先左 再根 再右
后序遍歷: 先左 再右 再根
這里的根,指的是每個(gè)分叉子樹(shù)(左右子樹(shù)的根節(jié)點(diǎn))根節(jié)點(diǎn),并不只是最開(kāi)始頭頂?shù)母?jié)點(diǎn),需要靈活思考理解,建議畫(huà)圖理解?。?/p>
二、代碼展示
#include<stdio.h> #include<stdlib.h> typedef struct Tree{ ? ?int data;?? ??? ??? ??? ??? ?//?? ?存放數(shù)據(jù)域 ?struct Tree *lchild;?? ??? ??? ?//?? ?遍歷左子樹(shù)指針 ?struct Tree *rchild;?? ??? ??? ?//?? ?遍歷右子樹(shù)指針 ? }Tree,*BitTree; BitTree CreateLink() { ?? ?int data; ?? ?int temp; ?? ?BitTree T; ?? ? ?? ?scanf("%d",&data);?? ??? ?//?? ?輸入數(shù)據(jù) ?? ?temp=getchar();?? ??? ??? ?//?? ?吸收空格 ?? ? ?? ?if(data == -1){?? ??? ??? ?//?? ?輸入-1 代表此節(jié)點(diǎn)下子樹(shù)不存數(shù)據(jù),也就是不繼續(xù)遞歸創(chuàng)建 ?? ??? ? ?? ??? ?return NULL; ?? ?}else{ ?? ??? ?T = (BitTree)malloc(sizeof(Tree));?? ??? ??? ?//?? ??? ?分配內(nèi)存空間 ?? ??? ?T->data = data;?? ??? ??? ??? ??? ??? ??? ??? ?//?? ??? ?把當(dāng)前輸入的數(shù)據(jù)存入當(dāng)前節(jié)點(diǎn)指針的數(shù)據(jù)域中 ?? ??? ? ?? ??? ?printf("請(qǐng)輸入%d的左子樹(shù): ",data);?? ??? ? ?? ??? ?T->lchild = CreateLink();?? ??? ??? ??? ??? ?//?? ??? ?開(kāi)始遞歸創(chuàng)建左子樹(shù) ?? ??? ?printf("請(qǐng)輸入%d的右子樹(shù): ",data);?? ??? ??? ? ?? ??? ?T->rchild = CreateLink();?? ??? ??? ??? ??? ?//?? ??? ?開(kāi)始到上一級(jí)節(jié)點(diǎn)的右邊遞歸創(chuàng)建左右子樹(shù) ?? ??? ?return T;?? ??? ??? ??? ??? ??? ??? ?//?? ??? ?返回根節(jié)點(diǎn) ?? ?}?? ? ?? ? } //?? ?先序遍歷 void ShowXianXu(BitTree T)?? ??? ??? ?//?? ??? ?先序遍歷二叉樹(shù) { ?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點(diǎn) ?? ?{ ?? ??? ?return; ?? ?} ?? ?printf("%d ",T->data); ?? ?ShowXianXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹(shù) ?? ?ShowXianXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹(shù) } //?? ?中序遍歷 void ShowZhongXu(BitTree T)?? ??? ??? ?//?? ??? ?先序遍歷二叉樹(shù) { ?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點(diǎn) ?? ?{ ?? ??? ?return; ?? ?} ?? ? ?? ?ShowZhongXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹(shù) ?? ?printf("%d ",T->data); ?? ?ShowZhongXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹(shù) ?? ? } //?? ?后序遍歷 void ShowHouXu(BitTree T)?? ??? ??? ?//?? ??? ?后序遍歷二叉樹(shù) { ?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點(diǎn) ?? ?{ ?? ??? ?return; ?? ?} ?? ? ?? ?ShowHouXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹(shù) ?? ?ShowHouXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹(shù) ?? ?printf("%d ",T->data); } int main() { ?? ?BitTree S; ?? ?printf("請(qǐng)輸入第一個(gè)節(jié)點(diǎn)的數(shù)據(jù):\n"); ?? ?S = CreateLink();?? ??? ??? ?//?? ??? ?接受創(chuàng)建二叉樹(shù)完成的根節(jié)點(diǎn) ?? ?printf("先序遍歷結(jié)果: \n"); ?? ?ShowXianXu(S);?? ??? ??? ??? ?//?? ??? ?先序遍歷二叉樹(shù) ?? ?printf("\n中序遍歷結(jié)果: \n"); ?? ?ShowZhongXu(S);?? ??? ??? ??? ?//?? ??? ?中序遍歷二叉樹(shù) ?? ? ?? ?printf("\n后序遍歷結(jié)果: \n"); ?? ?ShowHouXu(S);?? ??? ??? ??? ?//?? ??? ?后序遍歷二叉樹(shù) ?? ? ?? ?return 0;?? ? } ?? ?
到此這篇關(guān)于C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)先序、中序、后序及層次四種遍歷的文章就介紹到這了,更多相關(guān)C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?容器中map和unordered?map區(qū)別詳解
這篇文章主要為大家介紹了C++?容器中map和unordered?map區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11C語(yǔ)言靜態(tài)版通訊錄的設(shè)計(jì)與實(shí)現(xiàn)
靜態(tài)版通訊錄是一種簡(jiǎn)單的通訊錄實(shí)現(xiàn)方式,通過(guò)定義固定的數(shù)組大小來(lái)存儲(chǔ)聯(lián)系人信息。該方法不支持動(dòng)態(tài)增刪聯(lián)系人,但具有實(shí)現(xiàn)簡(jiǎn)單、易于理解的優(yōu)點(diǎn)。在程序設(shè)計(jì)中,需注意數(shù)組邊界溢出等問(wèn)題2023-04-04C語(yǔ)言求兩個(gè)正整數(shù)的最大公約數(shù)示例代碼
在C語(yǔ)言中求兩個(gè)數(shù)的最大公約數(shù)是學(xué)習(xí)循環(huán)語(yǔ)句的非常經(jīng)典的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言求兩個(gè)正整數(shù)的最大公約數(shù)的相關(guān)資料,需要的朋友可以參考下2021-12-12C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷毀詳解
函數(shù)棧幀(stack frame)就是函數(shù)調(diào)用過(guò)程中在程序的調(diào)用棧(call stack)所開(kāi)辟的空間,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷毀的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09詳解C++編程中對(duì)二進(jìn)制文件的讀寫(xiě)操作
這篇文章主要介紹了C++編程中對(duì)二進(jìn)制文件的讀寫(xiě)操作,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09