SDUTOJ1291資料結構上機測試4.1:二叉樹的遍歷與應用1
阿新 • • 發佈:2018-12-13
以SDUTOJ1291資料結構上機測試4.1:二叉樹的遍歷與應用1為例
https://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2711/pid/1291
思路:
遞迴實現,化解子問題解決。
先序:ABDCEF
中序:BDAECF
第一步:根據先序遍歷的特點,我們可以簡單地知道根節點為A
第二步:觀察中序,其中root節點A左側的BD必然是root的左子樹,A右側的ECF必定是root的右子樹
第三步:觀察左子樹BD,左子樹中的根節點必定是大樹的leftchild。在先序中大樹的leftchild位於root之後,所以左子樹的根節點是B。
第四步:同理,root的右子樹的節點ECF中的根節點也可以通過前序遍歷得到。root的右子樹節點ECF中的根節點也可以通過前序遍歷求得。在前序遍歷中,一定是先把root和root的所有左子樹節點遍歷完之後才會遍歷右子樹,並且遍歷的左子樹的第一個節點就是左子樹的根節點。同理,遍歷的右子樹的第一個節點就是右子樹的根節點。
第五步,觀察發現,上面的過程是遞迴的。先找到當前樹的根節點,然後劃分為左子樹,右子樹,然後進入左子樹重複上面的過程,然後進入右子樹重複上面的過程。最後就可以還原一棵樹了。該步遞迴的過程可以簡潔表達如下:
1 確定根,確定左子樹,確定右子樹。
2 在左子樹中遞迴。
3 在右子樹中遞迴。
4 列印當前根。
程式碼實現
#include <bits/stdc++.h> using namespace std; void make(int len, char *s1, char *s2, char *s) // s1為先序 s2為中序 { int i; if (len <= 0) return; // return 必不可少 否則死迴圈 else { for (i = 0; i < len; i++) { if (s1[0] == s2[i]) // 在中序中搜索根節點 實現遞迴 break; } } // 關鍵部分 make(i, s1 + 1, s2, s); // 搜尋上次搜尋左側部分 make(len - i - 1, s1 + i + 1, s2 + i + 1, s + i); // 搜尋上次搜尋右側部分 s[len - 1] = s1[0]; // 後序輸出 把遞迴找出的根節點從後存入 也就是列印當前根 } int main() { char s1[100], s2[100], s[100]; scanf("%s %s", s1, s2); int len = strlen(s1); // s[len] = '\0'; // 不要忘記封口 make(len, s1, s2, s); s[len] = '\0'; // 不要忘記封口 cout << s << endl; return 0; }