日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

二叉树的递归遍历和层序遍历(c/c++)

發(fā)布時間:2025/6/17 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉树的递归遍历和层序遍历(c/c++) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  • 遞歸遍歷:

二叉樹的三種遞歸遍歷為先序遍歷,中序遍歷和后續(xù)遍歷。它們相似之處在于都是對二叉樹的遞歸遍歷且對任何一個結(jié)點(diǎn)都經(jīng)過三次,區(qū)別之處在于哪一次對該結(jié)點(diǎn)進(jìn)行訪問,由此分為先,中,后序遍歷。所以對于任一結(jié)點(diǎn)都有:三次經(jīng)過,一次訪問。

先序遍歷:

僅以先序遍歷為例說明其思路。

當(dāng)我們對二叉樹進(jìn)行遍歷時,先對該結(jié)點(diǎn)內(nèi)的數(shù)據(jù)進(jìn)行訪問,然后依次遍歷它的左右孩子結(jié)點(diǎn),遞歸進(jìn)行直至結(jié)束。

例:對一個有三個結(jié)點(diǎn)的二叉樹,包含根結(jié)點(diǎn)A,左孩子結(jié)點(diǎn)B和右孩子結(jié)點(diǎn)C。先序遍歷的函數(shù)執(zhí)行過程如下:(下面的字母和數(shù)字表示函數(shù)的執(zhí)行步驟)

第一次函數(shù)調(diào)用:A,訪問根結(jié)點(diǎn)中的數(shù)據(jù),遞歸調(diào)用左孩子結(jié)點(diǎn)B,遞歸調(diào)用右孩子結(jié)點(diǎn)C。

第二次函數(shù)調(diào)用左孩子結(jié)點(diǎn) B:訪問左孩子結(jié)點(diǎn)內(nèi)的數(shù)據(jù),遞歸調(diào)用左孩子結(jié)點(diǎn)的左孩子結(jié)點(diǎn)B->left,遞歸調(diào)用左孩子結(jié)點(diǎn)的右孩子結(jié)點(diǎn)B->right。

第三次函數(shù)調(diào)用左孩子的左孩子結(jié)點(diǎn)B->left:該結(jié)點(diǎn)為空,不執(zhí)行。返回第二次函數(shù)調(diào)用。

第四次函數(shù)調(diào)用左孩子的右孩子結(jié)點(diǎn)B->right:該結(jié)點(diǎn)為空,不執(zhí)行。返回第二次函數(shù)調(diào)用。第二次函數(shù)調(diào)用執(zhí)行完畢,返回第一次函數(shù)調(diào)用中。

第五次函數(shù)調(diào)用右孩子結(jié)點(diǎn) C:訪問右孩子結(jié)點(diǎn)內(nèi)數(shù)據(jù),遞歸調(diào)用右孩子結(jié)點(diǎn)的左孩子結(jié)點(diǎn)C->left,遞歸調(diào)用右孩子結(jié)點(diǎn)的右孩子結(jié)點(diǎn)C->right。

第六次函數(shù)調(diào)用右孩子的左孩子結(jié)點(diǎn)C->left:該結(jié)點(diǎn)為空,不執(zhí)行。返回第五次函數(shù)調(diào)用。

第七次函數(shù)調(diào)用右孩子的右孩子結(jié)點(diǎn)C->right:該結(jié)點(diǎn)為空,不執(zhí)行。返回第五次函數(shù)調(diào)用。第五次函數(shù)調(diào)用執(zhí)行完畢,返回第一次函數(shù)調(diào)用。

第一次函數(shù)調(diào)用執(zhí)行完畢。遞歸結(jié)束。

void preorder(btNode* p) {if (p != NULL){visit(p);preorder(p->lc);preorder(p->rc);} }

中序遍歷:

void inorder(btNode* p) {if (p != NULL){inorder(p->lc);visit(p);inorder(p->rc);} }

后序遍歷:

void postorder(btNode* p) {if (p != NULL){postorder(p->lc);postorder(p->rc);visit(p);} }

對于下圖中的樹:

先序遍歷結(jié)果為:ABDECF ? 根 ? 左 ? 右

中序遍歷結(jié)果為:DBEAFC ? 左 ? 根 ? 右

后序遍歷結(jié)果為:DEBFCA ? 左 ? 右 ? 根

中序與先(后)序可唯一確定一顆二叉樹。

  • 層序遍歷:

二叉樹的層序遍歷的實(shí)現(xiàn)思路:

建立一個輔助數(shù)據(jù)結(jié)構(gòu)隊列,在此采用大小為10的循環(huán)隊列。初始先將二叉樹根節(jié)點(diǎn)入隊,從而使得隊列不為空,接下來進(jìn)入到循環(huán)中,當(dāng)隊列不為空時,隊列中元素出隊,訪問出隊元素中的數(shù)據(jù),并在出隊時將其左右孩子挨個入隊,每出隊一個結(jié)點(diǎn),將其左右孩子分別入隊,直至隊列為空,此時所有結(jié)點(diǎn)都被訪問過了。

void level(btNode* p) {int front, rear;front = rear = 0;btNode* que[10];//構(gòu)造一個大小為10的簡單循環(huán)隊列if (p != NULL){rear = (rear + 1) % 10;que[rear] = p;while (rear != front){front = (front + 1) % 10;std::cout << que[front]->data << ' ';//出隊時進(jìn)行輸出或進(jìn)行操作if (que[front]->lc != NULL){rear = (rear + 1) % 10;que[rear] = que[front]->lc;}if (que[front]->rc != NULL){rear = (rear + 1) % 10;que[rear] = que[front]->rc;}}} }

關(guān)于樹的遍歷完整代碼如下:

#include<iostream> typedef struct btNode {char data;//結(jié)點(diǎn)中的信息struct btNode* lc;//左孩子結(jié)點(diǎn)struct btNode* rc;//右孩子結(jié)點(diǎn) }btNode;btNode* initial(char* ele, int num);//用數(shù)組初始化一棵樹(默認(rèn)創(chuàng)建一棵完全二叉樹) void preorder(btNode* p);//先序遍歷 void inorder(btNode* p);//中序遍歷 void postorder(btNode* p);//后續(xù)遍歷 void level(btNode* p);//層序遍歷 int main() {using namespace std;char data[6] = { 'a', 'b', 'c', 'd', 'e', 'f' };btNode* p = initial(data, 6);cout << "先序遍歷: ";preorder(p);cout << endl;cout << "中序遍歷: ";inorder(p);cout << endl;cout << "后序遍歷: ";postorder(p);cout << endl;cout << "層序遍歷: ";level(p);cout << endl;return 0; } btNode* initial(char* ele, int num) {if (num<1)return NULL;btNode* temp = new btNode[num];int i = 0;while (i < num)//將所有結(jié)點(diǎn)的左右子樹置為空{(diào)temp[i].lc = NULL;temp[i].rc = NULL;++i;}i = 0;while (i < num/2)//通過完全二叉樹的順序存儲來創(chuàng)建樹的結(jié)構(gòu){if (2*i+1<num)temp[i].lc = temp + 2 * i + 1;if (2*i+2<num)temp[i].rc = temp + 2 * i + 2;++i;}for (i = 0; i < num; i++)//對樹中的每個結(jié)點(diǎn)賦值temp[i].data = ele[i];return temp; } void preorder(btNode* p) {if (p != NULL){std::cout << p->data << ' ';preorder(p->lc);preorder(p->rc);} } void inorder(btNode* p) {if (p != NULL){inorder(p->lc);std::cout << p->data << ' ';inorder(p->rc);} } void postorder(btNode* p) {if (p != NULL){postorder(p->lc);postorder(p->rc);std::cout << p->data << ' ';} } void level(btNode* p) {int front, rear;front = rear = 0;btNode* que[10];if (p != NULL){rear = (rear + 1) % 10;que[rear] = p;while (rear != front){front = (front + 1) % 10;std::cout << que[front]->data << ' ';if (que[front]->lc != NULL){rear = (rear + 1) % 10;que[rear] = que[front]->lc;}if (que[front]->rc != NULL){rear = (rear + 1) % 10;que[rear] = que[front]->rc;}}} }

其中數(shù)組中的輸入為下圖中的樹:

程序的輸出結(jié)果為:

二叉樹非遞歸遍歷可參考:

二叉樹的非遞歸遍歷(c/c++)_Little_ant_的博客-CSDN博客

總結(jié)

以上是生活随笔為你收集整理的二叉树的递归遍历和层序遍历(c/c++)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。