前序中序确认二叉树 7-23 还原二叉树(25 分)
7-23?還原二叉樹(25?分)
給定一棵二叉樹的先序遍歷序列和中序遍歷序列,要求計算該二叉樹的高度。
輸入格式:
輸入首先給出正整數(shù)N(≤50),為樹中結(jié)點總數(shù)。下面兩行先后給出先序和中序遍歷序列,均是長度為N的不包含重復(fù)英文字母(區(qū)別大小寫)的字符串。
輸出格式:
輸出為一個整數(shù),即該二叉樹的高度。
輸入樣例:
9 ABDFGHIEC FDHGIBEAC輸出樣例:
5 作者:?DS課程組 單位:?浙江大學(xué) 時間限制:?400ms 內(nèi)存限制:?64MB 代碼長度限制:?16KB代碼:
#include<iostream> #include<string> using namespace std; string pre, mid; int n, num = -1; int gethigh(int start, int end) {num++;int i, j;for (i = start; i < end; i++)if (pre[num] == mid[i]) break;if (i == end) return 0;int left = 0, right = 0;if (start < i) left = gethigh(start, i);if (i + 1 < end) right = gethigh(i + 1, end);return left > right ? left + 1 : right + 1; } int main() {cin >> n;cin >> pre;cin >> mid;cout << gethigh(0, n) << endl; }要求:根據(jù)樹的前序和中序確認后序
思路:首先我們要知道中序的意義,拿二叉搜索樹來舉例,對搜索樹進行中序遍歷并輸出,最后可以得到(由小到大)的有序數(shù)組。所以中序其實就相當(dāng)于給每個元素從左往右標(biāo)了序號,做過 二叉樹橫向輸出 的朋友應(yīng)該知道,那題在輸出時要知道該節(jié)點是從左往右數(shù)的第幾個,然后才能算需要輸出幾個‘—’來保持樹狀。 簡而言之,中序就是橫向地給節(jié)點標(biāo)記。
? ?其次,我們要知道前序的意義,前序的第一個節(jié)點一定是整棵樹的根節(jié)點。但是對于第二個節(jié)點,我們無法知道它是根節(jié)點的左子樹還是根節(jié)點的右子樹。
? ? ? ? ? ?假如前序的第一個節(jié)點 在 中序里排在第 5 個位置,而前序的第二個節(jié)點 排在中序的第 3 個位置,那么這時候,我們可以判定,第二個節(jié)點是第一個節(jié)點的左子樹。 結(jié)合上面的解釋應(yīng)該可以自己理解了,如果還沒頓悟的話往下看。? 為什么呢? 因為對于第二個節(jié)點來說只有兩個可能:1.它是第一個節(jié)點的左子樹 2.它是第一個節(jié)點的右子樹。我們前面說過,中序是橫向地給樹標(biāo)記,第二個節(jié)點的位置小于第一個,說明二在一的左邊。所以,這時候可以認定,它是一的左子樹。
我們可以結(jié)合樣例來看一看
| num | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ? |
| pre | A | B | D | F | G | H | I | E | C | ? |
| mid | F | D | H | G | I | B | E | A | C | ? |
對num 從0到8 一一檢查:
0:確立根節(jié)點A,并在mid中找到A
1:在mid中找到B,如果 B <7,則為A的左子樹;如果 B>7,則B為A的右子樹。 B為5,A的左子樹。
2:在mid中找到D,如果D<5,則為B的左子樹,如果5<D<7,則為B的右子樹,如果D>7,則為A的右子樹。D=1,B的左子樹。
3:在mid中找到F,如果F<1,則為D的左子樹;
? ? ? ? ? ? ? ? ? ? ? ? 如果1<F<5,則為D的右子樹(B的左子樹是D,所以顯然不可能是B的左子樹);
? ? ? ? ? ? ? ? ? ? ? ?如果5<F<7,則為B的右子樹;
? ? ? ? ? ? ? ? ? ? ? ?如果7<F,則為A的右子樹;
4.以此類推。
這樣子推有沒有覺得特別繁瑣?要一個個判斷過去多累人啊! 上面的方法主要是給人判斷的,如果你要徒手畫,就是這個思路。 要用代碼實現(xiàn)的話,利用分治的思想,遞歸分解,把樹的規(guī)模一步步縮小,就能確認出二叉樹了。
上面講了這么多,其實并不需要把二叉樹完整的弄出來,做一個gethigh(int start,int end) 函數(shù)就行了。
start,end 是開始與結(jié)束的位置。比如確認了A后,左邊只要掃描[0,7),右邊只要掃描(7,8]。
left = gethigh(…,…)? ?體現(xiàn)的是 分治的思想
return 取兩邊大的那個再+1,如果左右都是空,就是返回1.
num放在了外面,確保每次都遞進一個搜索。開始做的時候,我把num作為形參,這樣導(dǎo)致left之后的num和right的num不同步,然后調(diào)試了半天 _(:з」∠)_
最后如果題目要求創(chuàng)建二叉樹并后序輸出
代碼:
#include<iostream> #include<string.h> #include<stdlib.h> #include<stdio.h> using namespace std; typedef char Element; struct Node {Element data;struct Node *lchild;struct Node *rchild; }; typedef struct Node BTNode; typedef struct Node * BTree; char pre[220]; char mid[220]; BTree creat(char *pre, char *in, int len) {BTree p = (BTree)malloc(sizeof(BTNode));if (len < 1)return NULL;int i = 0; //每次遞歸i都初始為0while (in[i] != pre[0])i++; //找出位置p->lchild = creat(pre + 1, in, i);p->rchild = creat(pre + i + 1, in + i + 1, len - i - 1);p->data = pre[0];return p; } void post(BTree root) {if (root){if (root->lchild)post(root->lchild);if (root->rchild)post(root->rchild);cout << root->data;} } int main() {BTree root;cin >> pre;cin >> mid;root = creat(pre, mid, strlen(pre));post(root);cout << endl; }轉(zhuǎn)載于:https://www.cnblogs.com/childwang/p/8280274.html
總結(jié)
以上是生活随笔為你收集整理的前序中序确认二叉树 7-23 还原二叉树(25 分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Vista操作系统中通过manifes
- 下一篇: 什么是 Trait