對於二叉樹T,能夠遞歸定義它的先序遍歷、中序遍歷和後序遍歷以下: PreOrder(T)=T的根節點+PreOrder(T的左子樹)+PreOrder(T的右子樹) InOrder(T)=InOrder(T的左子樹)+T的根節點+InOrder(T的右子樹) PostOrder(T)=PostOrder(T的左子樹)+PostOrder(T的右子樹)+T的根節點 其中加號表示字符串鏈接運算。例如,對下圖所示的二叉樹,先序遍歷爲DBACEGF,中序遍歷爲ABCDEFG。
輸入一棵二叉樹的先序遍歷序列和中序遍歷序列,輸出它的廣度優先遍歷序列。 node
第一行爲一個整數t(0<t<10),表示測試用例個數。 如下t行,每行輸入一個測試用例,包含兩個字符序列s1和s2,其中s1爲一棵二叉樹的先序遍歷序列,s2爲中序遍歷序列。s1和s2之間用一個空格分隔。序列只包含大寫字母,而且每一個字母最多隻會出現一次。 ios
爲每一個測試用例單獨一行輸出廣度優先遍歷序列。 測試
2 DBACEGF ABCDEFG BCAD CBAD
DBEACGF BCAD
本題很直白,就是知道二叉樹前序和中序遍歷的結果,而後輸出廣度優先遍歷的結果。明白二叉樹遍歷的遞歸方式就能很明白的看出解法。 spa
對於每棵樹或者子樹,他的前序和中序遍歷序列都有特定的性質,即前序序列開始的節點必定是根節點。那麼中序序列中次節點將序列分城左右兩個子序列,分別對應左右子樹中序遍歷結果。如此左右子樹節點數目已知,那麼就能夠在前序序列中找出左右子樹前序遍歷結果,這樣遞歸處理就能還原二叉樹,而後調用BSF方法便可。 code
PS:二叉樹處理方法大都與遞歸相關,並且遞歸的中心在於樹或者子樹的根,緊緊抓住至一點就能化繁爲簡。另外,其實前序遍歷算是廣度優先遍歷。 orm
// Problem#: 1935 // Submission#: 1895987 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include <iostream> #include <string> #include <queue> using namespace std; struct node{ char left; char right; }buffer[30]; void tree(string str1, string str2) { int size = str1.size(); if (size == 0) return ; int a = str2.find(str1[0]); int b = str1[0] - 'A'; string l1, l2, r1, r2; l1 = a ? str1.substr(1, a): ""; l2 = a ? str2.substr(0, a): ""; r1 = (a < size - 1) ? str1.substr(a + 1, size - 1 - a): ""; r2 = (a < size - 1) ? str2.substr(a + 1, size - 1 - a): ""; buffer[b].left = a ? l1[0] : '\0'; buffer[b].right = (a < size - 1) ? r1[0] : '\0'; tree(l1, l2); tree(r1, r2); } void bfs(char c) { queue<char> tmp; tmp.push(c); while (!tmp.empty()) { char t = tmp.front(); cout << t; tmp.pop(); node n = buffer[t - 'A']; if (n.left != '\0') tmp.push(n.left); if (n.right != '\0') tmp.push(n.right); } } int main() { int t; string preOrder, inOrder; cin >> t; while (t--) { cin >> preOrder >> inOrder; tree(preOrder, inOrder); bfs(preOrder[0]); cout << endl; } return 0; }