C語言數(shù)據(jù)結(jié)構(gòu)二叉樹先序、中序、后序及層次四種遍歷
一、圖示展示
(1)先序遍歷
先序遍歷可以想象為,一個小人從一棵二叉樹根節(jié)點為起點,沿著二叉樹外沿,逆時針走一圈回到根節(jié)點,路上遇到的元素順序,就是先序遍歷的結(jié)果
先序遍歷結(jié)果為:A B D H I E J C F K G

動畫演示:
記住小人沿著外圍跑一圈(直到跑回根節(jié)點),多看幾次動圖便能理解


(2)中序遍歷
中序遍歷可以看成,二叉樹每個節(jié)點,垂直方向投影下來(可以理解為每個節(jié)點從最左邊開始垂直掉到地上),然后從左往右數(shù),得出的結(jié)果便是中序遍歷的結(jié)果
中遍歷結(jié)果為:H D I B E J A F K C G

動畫展示:
記住,中序遍歷就是從最左邊開始,把每個節(jié)點垂直投影到同一直線上,然后從左往右讀值就可以了,多看幾遍動圖就理解了

(3)后序遍歷
后序遍歷就像是剪葡萄,我們要把一串葡萄剪成一顆一顆的。
還記得我上面提到先序遍歷繞圈的路線么?(不記得翻上面理解)
就是圍著樹的外圍繞一圈,如果發(fā)現(xiàn)一剪刀就能剪下的葡萄(必須是一顆葡萄)(也就是葡萄要一個一個掉下來,不能一口氣掉超過1個這樣),就把它剪下來,組成的就是后序遍歷了。
后序遍歷中,根節(jié)點默認最后面
后序遍歷結(jié)果:H I D J E B K F G C A

動畫展示:

(4)層次遍歷
層次遍歷很好理解,就是從根節(jié)點開始,一層一層,從上到下,每層從左到右,依次寫值就可以了
層次遍歷結(jié)果:A B C D E F G H I J K

解釋外圈跑的意思:
繞著外圍跑一整圈的真正含義是:遍歷所有結(jié)點時,都先往左孩子走,再往右孩子走。
(5)口訣
先序遍歷: 先根 再左 再右
中序遍歷: 先左 再根 再右
后序遍歷: 先左 再右 再根
這里的根,指的是每個分叉子樹(左右子樹的根節(jié)點)根節(jié)點,并不只是最開始頭頂?shù)母?jié)點,需要靈活思考理解,建議畫圖理解?。?/p>
二、代碼展示
#include<stdio.h>
#include<stdlib.h>
typedef struct Tree{
?
?int data;?? ??? ??? ??? ??? ?//?? ?存放數(shù)據(jù)域
?struct Tree *lchild;?? ??? ??? ?//?? ?遍歷左子樹指針
?struct Tree *rchild;?? ??? ??? ?//?? ?遍歷右子樹指針
?
}Tree,*BitTree;
BitTree CreateLink()
{
?? ?int data;
?? ?int temp;
?? ?BitTree T;
?? ?
?? ?scanf("%d",&data);?? ??? ?//?? ?輸入數(shù)據(jù)
?? ?temp=getchar();?? ??? ??? ?//?? ?吸收空格
?? ?
?? ?if(data == -1){?? ??? ??? ?//?? ?輸入-1 代表此節(jié)點下子樹不存數(shù)據(jù),也就是不繼續(xù)遞歸創(chuàng)建
?? ??? ?
?? ??? ?return NULL;
?? ?}else{
?? ??? ?T = (BitTree)malloc(sizeof(Tree));?? ??? ??? ?//?? ??? ?分配內(nèi)存空間
?? ??? ?T->data = data;?? ??? ??? ??? ??? ??? ??? ??? ?//?? ??? ?把當前輸入的數(shù)據(jù)存入當前節(jié)點指針的數(shù)據(jù)域中
?? ??? ?
?? ??? ?printf("請輸入%d的左子樹: ",data);?? ??? ?
?? ??? ?T->lchild = CreateLink();?? ??? ??? ??? ??? ?//?? ??? ?開始遞歸創(chuàng)建左子樹
?? ??? ?printf("請輸入%d的右子樹: ",data);?? ??? ??? ?
?? ??? ?T->rchild = CreateLink();?? ??? ??? ??? ??? ?//?? ??? ?開始到上一級節(jié)點的右邊遞歸創(chuàng)建左右子樹
?? ??? ?return T;?? ??? ??? ??? ??? ??? ??? ?//?? ??? ?返回根節(jié)點
?? ?}?? ?
?? ?
}
//?? ?先序遍歷
void ShowXianXu(BitTree T)?? ??? ??? ?//?? ??? ?先序遍歷二叉樹
{
?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點
?? ?{
?? ??? ?return;
?? ?}
?? ?printf("%d ",T->data);
?? ?ShowXianXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹
?? ?ShowXianXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹
}
//?? ?中序遍歷
void ShowZhongXu(BitTree T)?? ??? ??? ?//?? ??? ?先序遍歷二叉樹
{
?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點
?? ?{
?? ??? ?return;
?? ?}
?? ?
?? ?ShowZhongXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹
?? ?printf("%d ",T->data);
?? ?ShowZhongXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹
?? ?
}
//?? ?后序遍歷
void ShowHouXu(BitTree T)?? ??? ??? ?//?? ??? ?后序遍歷二叉樹
{
?? ?if(T==NULL)?? ??? ??? ??? ??? ??? ?//?? ?遞歸中遇到NULL,返回上一層節(jié)點
?? ?{
?? ??? ?return;
?? ?}
?? ?
?? ?ShowHouXu(T->lchild);?? ??? ??? ?//?? ?遞歸遍歷左子樹
?? ?ShowHouXu(T->rchild);?? ??? ??? ?//?? ?遞歸遍歷右子樹
?? ?printf("%d ",T->data);
}
int main()
{
?? ?BitTree S;
?? ?printf("請輸入第一個節(jié)點的數(shù)據(jù):\n");
?? ?S = CreateLink();?? ??? ??? ?//?? ??? ?接受創(chuàng)建二叉樹完成的根節(jié)點
?? ?printf("先序遍歷結(jié)果: \n");
?? ?ShowXianXu(S);?? ??? ??? ??? ?//?? ??? ?先序遍歷二叉樹
?? ?printf("\n中序遍歷結(jié)果: \n");
?? ?ShowZhongXu(S);?? ??? ??? ??? ?//?? ??? ?中序遍歷二叉樹
?? ?
?? ?printf("\n后序遍歷結(jié)果: \n");
?? ?ShowHouXu(S);?? ??? ??? ??? ?//?? ??? ?后序遍歷二叉樹
?? ?
?? ?return 0;?? ?
} ?? ?到此這篇關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)二叉樹先序、中序、后序及層次四種遍歷的文章就介紹到這了,更多相關(guān)C語言數(shù)據(jù)結(jié)構(gòu)遍歷內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?容器中map和unordered?map區(qū)別詳解
這篇文章主要為大家介紹了C++?容器中map和unordered?map區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
C語言靜態(tài)版通訊錄的設(shè)計與實現(xiàn)
靜態(tài)版通訊錄是一種簡單的通訊錄實現(xiàn)方式,通過定義固定的數(shù)組大小來存儲聯(lián)系人信息。該方法不支持動態(tài)增刪聯(lián)系人,但具有實現(xiàn)簡單、易于理解的優(yōu)點。在程序設(shè)計中,需注意數(shù)組邊界溢出等問題2023-04-04

