C語(yǔ)言之二叉樹(shù)的遍歷
0.寫(xiě)在前面
認(rèn)識(shí)二叉樹(shù)結(jié)構(gòu)最簡(jiǎn)單的方式就是遍歷二叉樹(shù)。所謂遍歷二叉樹(shù)就是按照某種特定的規(guī)則,對(duì)二叉樹(shù)的每一個(gè)節(jié)點(diǎn)進(jìn)行訪(fǎng)問(wèn),且每個(gè)節(jié)點(diǎn)只訪(fǎng)問(wèn)一次。
二叉樹(shù)遍歷的規(guī)則一般有四種:前序遍歷、中序遍歷、后序遍歷和層序遍歷。其中,前三種較為簡(jiǎn)單且實(shí)現(xiàn)方式大同小異。
1.前序遍歷:先訪(fǎng)問(wèn)根節(jié)點(diǎn),再遍歷左右子樹(shù);
2.中序遍歷:先遍歷左子樹(shù),再訪(fǎng)問(wèn)根節(jié)點(diǎn),再遍歷右子樹(shù);
3.后序遍歷:先遍歷左子樹(shù),再遍歷右子樹(shù),再訪(fǎng)問(wèn)根節(jié)點(diǎn)。
簡(jiǎn)單記憶:前(根,左,右)、中(左,根,右)、后(左,右,根)。
在遍歷二叉樹(shù)之前,首先得擁有一棵二叉樹(shù)。因?yàn)槟壳斑€沒(méi)有學(xué)習(xí)如何構(gòu)建二叉樹(shù),所以此處我們用最原始的辦法——申請(qǐng)N個(gè)節(jié)點(diǎn),將它們手動(dòng)拼接為二叉樹(shù)。
typedef int BTDataType; //二叉樹(shù)節(jié)點(diǎn)的結(jié)構(gòu) typedef struct BTNode { BTDataType data; struct BTNode* left; struct BTNode* right; }BTNode; //定義一個(gè)申請(qǐng)新節(jié)點(diǎn)的函數(shù) BTNode* BuyBTNode(BTDataType data) { BTNode* newNode = (BTNode*)malloc(sizeof(BTNode)); if (newNode == NULL) { perror("malloc fail"); exit(-1); } newNode->data = data; newNode->left = NULL; newNode->right = NULL; return newNode; } int main() { //手動(dòng)申請(qǐng)節(jié)點(diǎn)加連接 BTNode* n1 = BuyBTNode(1); BTNode* n2 = BuyBTNode(2); BTNode* n3 = BuyBTNode(3); BTNode* n4 = BuyBTNode(4); BTNode* n5 = BuyBTNode(5); BTNode* n6 = BuyBTNode(6); n1->left = n2; n1->right = n4; n2->left = n3; n4->left = n5; n4->right = n6; return 0; }
1.前序遍歷
前序遍歷:先訪(fǎng)問(wèn)根節(jié)點(diǎn),再訪(fǎng)問(wèn)左子樹(shù),再訪(fǎng)問(wèn)右子樹(shù);
void PrevOrder (BTNode* root)
為了更好的理解前序遍歷的規(guī)則,接下來(lái)展示一下詳細(xì)步驟。
步驟詳解
1.先訪(fǎng)問(wèn)根節(jié)點(diǎn) (data = 1),再訪(fǎng)問(wèn)左子樹(shù);
2.再訪(fǎng)問(wèn)左子樹(shù)的根節(jié)點(diǎn)(data = 2),再訪(fǎng)問(wèn)左子樹(shù)的左子樹(shù);
3.依舊先訪(fǎng)問(wèn)根節(jié)點(diǎn)(data = 3),此時(shí) n3 節(jié)點(diǎn)的左右子樹(shù)都為 NULL ,則不再往下遞歸,回到上一層;接著訪(fǎng)問(wèn)上一層的右子樹(shù);
4.因?yàn)?n2 節(jié)點(diǎn)的右子樹(shù)為 NULL,所以繼續(xù)返回上一層;訪(fǎng)問(wèn)上一層的右子樹(shù);
5.訪(fǎng)問(wèn)右子樹(shù)的根節(jié)點(diǎn)(data = 4),再訪(fǎng)問(wèn)右子樹(shù)的左子樹(shù);先左子樹(shù)的根節(jié)點(diǎn)(data = 5),n5 節(jié)點(diǎn)的左右子樹(shù)都為 NULL,返回上一層訪(fǎng)問(wèn)右子樹(shù)(data = 6),同樣 n6 節(jié)點(diǎn)的左右子樹(shù)都為 NULL,返回上一層。
至此每個(gè)節(jié)點(diǎn)都訪(fǎng)問(wèn)完畢,總體的訪(fǎng)問(wèn)順序是這樣的:
按照訪(fǎng)問(wèn)順序打印的結(jié)果應(yīng)該是(空節(jié)點(diǎn)用 NULL 表示):
代碼實(shí)現(xiàn)
按照前序遍歷的邏輯,前序遍歷的實(shí)現(xiàn)肯定是離不開(kāi)遞歸。
void PrevOrder(BTNode* root) { if (root == NULL) { printf("NULL ");//空節(jié)點(diǎn)用 NULL 表示 return; } printf("%d ", root->data);//前序在前 PrevOrder(root->left); PrevOrder(root->right); }
運(yùn)行程序,看結(jié)果是否與之前推理的結(jié)果一致:
int main() { //手動(dòng)申請(qǐng)節(jié)點(diǎn)加連接 BTNode* n1 = BuyBTNode(1); BTNode* n2 = BuyBTNode(2); BTNode* n3 = BuyBTNode(3); BTNode* n4 = BuyBTNode(4); BTNode* n5 = BuyBTNode(5); BTNode* n6 = BuyBTNode(6); n1->left = n2; n1->right = n4; n2->left = n3; n4->left = n5; n4->right = n6; PrevOrder(n1); return 0; }
2.中序遍歷
前中后序三種遍歷大同小異,實(shí)現(xiàn)代碼也幾乎相同。
void InOrder(BTNode* root)
步驟詳解
代碼實(shí)現(xiàn)
void InOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } PrevOrder(root->left); printf("%d ", root->data);//中序在中 PrevOrder(root->right); }
3.后序遍歷
步驟詳解
參考1、2。
代碼實(shí)現(xiàn)
void PostOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } PostOrder(root->left); PostOrder(root->right); printf("%d ", root->data);//后序在后 }
到此這篇關(guān)于C語(yǔ)言之二叉樹(shù)的遍歷的文章就介紹到這了,更多相關(guān)二叉樹(shù)的遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)詳解
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)先序、中序、后序及層次四種遍歷
- 詳細(xì)了解C語(yǔ)言二叉樹(shù)的建立與遍歷
- C語(yǔ)言二叉樹(shù)的三種遍歷方式的實(shí)現(xiàn)及原理
- C語(yǔ)言二叉樹(shù)常見(jiàn)操作詳解【前序,中序,后序,層次遍歷及非遞歸查找,統(tǒng)計(jì)個(gè)數(shù),比較,求深度】
- C語(yǔ)言非遞歸后序遍歷二叉樹(shù)
- C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)的非遞歸后序遍歷算法
相關(guān)文章
c++ 判斷是64位還是32位系統(tǒng)的實(shí)例
這篇文章主要介紹了c++ 判斷是64位還是32位系統(tǒng)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12C++實(shí)現(xiàn)簡(jiǎn)單FTP客戶(hù)端軟件開(kāi)發(fā)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單FTP客戶(hù)端軟件開(kāi)發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼
在本篇文章里小編給大家整理的是一篇關(guān)于C++ 遞歸遍歷文件并計(jì)算MD5的實(shí)例代碼,有興趣的朋友們可以學(xué)習(xí)參考下。2021-07-07利用C語(yǔ)言實(shí)現(xiàn)2048小游戲的方法
2048是比較流行的一款數(shù)字游戲,相信對(duì)大家來(lái)說(shuō)都不陌生,這篇文章給大家分享了利用C語(yǔ)言實(shí)現(xiàn)2048小游戲的方法,對(duì)大家學(xué)習(xí)理解C語(yǔ)言具有一定的參考借鑒價(jià)值,有需要的朋友們下面來(lái)一起看看吧。2016-10-10C++?測(cè)試框架GoogleTest入門(mén)介紹
這篇文章主要為大家介紹了C++測(cè)試框架GoogleTest入門(mén)基礎(chǔ),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04數(shù)據(jù)結(jié)構(gòu)之伸展樹(shù)詳解
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之伸展樹(shù)詳解,本文對(duì)伸展樹(shù)(Splay Tree)的單旋轉(zhuǎn)操作、一字型旋轉(zhuǎn)、之字形旋轉(zhuǎn)區(qū)間操作等理論知識(shí)做了講解,并給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-08-08一起來(lái)看看C語(yǔ)言的預(yù)處理注意點(diǎn)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言的預(yù)處理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03