国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

二叉樹的重建

2019-11-06 06:01:50
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

在http://blog.csdn.net/hacker_zhidian/article/details/60586445這篇文章中我們看了一下二叉樹的四種遍歷方式,接下來(lái)我們看一下關(guān)于二叉樹的重建問題,什么叫二叉樹的重建呢?

比方說給你一棵二叉樹的前序遍歷順序和中序遍歷順序,要求你求出這顆二叉樹的后序遍歷順序。來(lái)看一下個(gè)具體的例題數(shù)據(jù),給定一個(gè)二叉樹的信息:

二叉樹節(jié)點(diǎn)數(shù): 5 前序遍歷順序:1 2 3 4 5 中序遍歷順序:3 2 4 1 5 求后續(xù)遍歷順序?

像這種題目咋一看沒什么頭緒啊,如果不熟悉二叉樹的性質(zhì),這種題是挺費(fèi)腦的。但是我們仔細(xì)想想,二叉樹的前序遍歷順序是:根節(jié)點(diǎn) –> 左子樹 –> 右子樹 中序遍歷的順序是:左子樹 –> 根節(jié)點(diǎn) –> 右子樹。

那么從上面的數(shù)據(jù)中,我們可以知道,節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)就是整個(gè)二叉樹的根節(jié)點(diǎn)。之后再去中序遍歷的順序中找節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)位置,我們?cè)谥行虮闅v的順序中發(fā)現(xiàn), 節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)右邊有一個(gè)節(jié)點(diǎn)值為 5 的節(jié)點(diǎn),左邊有三個(gè)節(jié)點(diǎn)值分別為 3 2 4 的節(jié)點(diǎn)。Ok,根據(jù)中序遍歷的順序,我們知道節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)有兩棵子樹,節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn),接下來(lái),我們要對(duì)這個(gè)節(jié)點(diǎn)的做右子節(jié)點(diǎn)進(jìn)行討論:前序遍歷的順序的第二個(gè)節(jié)點(diǎn)(節(jié)點(diǎn)值為 2 )就是節(jié)點(diǎn)值為 1 的節(jié)點(diǎn)的左子節(jié)點(diǎn),接下來(lái)繼續(xù)查找這個(gè)節(jié)點(diǎn)值為 2 的節(jié)點(diǎn)在中序遍歷中的位置,我們發(fā)現(xiàn)節(jié)點(diǎn)值為 2 的節(jié)點(diǎn)在中序遍歷中也存在左右子節(jié)點(diǎn),那么繼續(xù)對(duì)它的左右子節(jié)點(diǎn)討論。。。

整個(gè)過程的代碼,也是這個(gè)問題的核心代碼:

// 重建二叉樹以第 n 個(gè)節(jié)點(diǎn)為根節(jié)點(diǎn)的子二叉樹,l 為二叉樹節(jié)點(diǎn)的左邊界,r 為右邊界void rec(int l, int r, int n) { if(l >= r) { node[n].w = INF; // 如果當(dāng)前節(jié)點(diǎn)為空,那么賦值為 INF return ; } int root = PRe[pos++]; node[n].w = root; // 獲取當(dāng)前節(jié)點(diǎn)儲(chǔ)存的值 node[n].l = 2 * n; // 當(dāng)前節(jié)點(diǎn)左孩子所在數(shù)組下標(biāo) node[n].r = 2 * n + 1; // 當(dāng)前節(jié)點(diǎn)右孩子節(jié)點(diǎn)所在數(shù)組下標(biāo) int m = find(in, in+r, root) - in; // 得到當(dāng)前節(jié)點(diǎn)在中序遍歷數(shù)組中的下標(biāo) rec(l, m, 2*n); // 重建左子樹 rec(m+1, r, 2*n+1); // 重建右子樹 }

上述代碼中,node儲(chǔ)存的是二叉樹節(jié)點(diǎn)的信息數(shù)組。下面給出完整的代碼:

/* * 根據(jù)二叉樹的前序遍歷和中序遍歷重建二叉樹, * 這里依然采用數(shù)組下標(biāo)來(lái)模擬指針 */#include <iostream>#include <algorithm>using namespace std;const int INF = -999999999; // 二叉樹節(jié)點(diǎn)為空的時(shí)候儲(chǔ)存的數(shù)值 const int N = 100010; // 二叉樹的節(jié)點(diǎn)個(gè)數(shù) int pre[N]; // 二叉樹前序遍歷的結(jié)果 int in[N]; // 二叉樹中序遍歷的結(jié)果 int pos; struct Node { // 節(jié)點(diǎn)信息結(jié)構(gòu)體 int l; // 節(jié)點(diǎn)的左孩子所在數(shù)組下標(biāo) int r; // 節(jié)點(diǎn)的右孩子所在數(shù)組下標(biāo) int w; // 節(jié)點(diǎn)的值 }; Node node[N]; // 儲(chǔ)存二叉樹節(jié)點(diǎn)信息的數(shù)組 // 重建二叉樹的第 n 個(gè)節(jié)點(diǎn)為根節(jié)點(diǎn)的子二叉樹, l 為二叉樹節(jié)點(diǎn)的左邊界,r 為右邊界void rec(int l, int r, int n) { if(l >= r) { node[n].w = INF; // 如果當(dāng)前節(jié)點(diǎn)為空,那么賦值為 -1 return ; } int root = pre[pos++]; node[n].w = root; // 獲取當(dāng)前節(jié)點(diǎn)儲(chǔ)存的值 node[n].l = 2 * n; // 當(dāng)前節(jié)點(diǎn)左孩子所在數(shù)組下標(biāo) node[n].r = 2 * n + 1; // 當(dāng)前節(jié)點(diǎn)右孩子節(jié)點(diǎn)所在數(shù)組下標(biāo) int m = find(in, in+r, root) - in; // 得到當(dāng)前節(jié)點(diǎn)在中序遍歷數(shù)組中的下標(biāo) rec(l, m, 2*n); // 重建左子樹 rec(m+1, r, 2*n+1); // 重建右子樹 }// 后序遍歷重建的二叉樹 void postOrderParse(int n) { if(node[n].w == INF) { // 如果當(dāng)前節(jié)點(diǎn)為空,那么結(jié)束輸出 return ; } postOrderParse(2*n); postOrderParse(2*n+1); // 這里輸出沒有嚴(yán)格的控制空格個(gè)數(shù),在 OJ 上做題的小伙伴注意一下 cout << node[n].w << " "; } int main() { int n; cin >> n; for(int i = 0; i < n; i++) { cin >> pre[i]; } for(int i = 0; i < n; i++) { cin >> in[i]; } rec(0, n, 1); // 從二叉樹根節(jié)點(diǎn)開始重建二叉樹 cout << "該二叉樹的后序遍歷:" << endl; postOrderParse(1); return 0;}

好了。來(lái)看一下運(yùn)行結(jié)果:

這里寫圖片描述

我們可以手工構(gòu)造出這棵二叉樹:

這里寫圖片描述

根據(jù)二叉樹的遍歷順序,我們可以很容易得到該二叉樹的后續(xù)遍歷,和程序執(zhí)行的結(jié)果一樣。這種二叉樹重建的思想可以解決一類問題,感興趣的小伙伴可以看一下這篇文章 http://blog.csdn.net/Hacker_ZhiDian/article/details/60771795。

或者試一下這道題https://www.patest.cn/contests/gplt/L2-011

好了,如果博客中有什么不正確的地方,還請(qǐng)多多指點(diǎn)。如果覺得我寫得不錯(cuò),請(qǐng)點(diǎn)個(gè)贊表示對(duì)我的支持。

謝謝觀看。。。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宣化县| 龙游县| 友谊县| 乌拉特中旗| 台湾省| 长乐市| 兴和县| 蕲春县| 景洪市| 南陵县| 南漳县| 康乐县| 巫溪县| 高州市| 泰安市| 葫芦岛市| 孙吴县| 佛教| 吉首市| 博客| 兴仁县| 闽清县| 大冶市| 车险| 娄烦县| 文成县| 宝清县| 准格尔旗| 修水县| 永嘉县| 平泉县| 福贡县| 郑州市| 开化县| 汉中市| 洪湖市| 泉州市| 昔阳县| 沈阳市| 元朗区| 思南县|