樹的相關小測試 題解
阿新 • • 發佈:2020-08-20
第一題和第三題起初想法都是構建樹的相關資料結構,但通過挖掘題目的性質,尤其是輸出要求,無需搭建一棵完整的樹。
1. 從下至上按層遍歷二叉樹
題意
給定一顆二叉樹,要求從下至上按層遍歷二叉樹,每層的訪問順序是從左到右,每一層單獨輸出一行。輸入形式為廣義表,它表示的二叉樹,結點元素型別為整型,且都大於0,例如:1( 2( 3 ( 4, 5 ) ), 6( 7, 8( 9, 10 ) ) )
。現要你從下至上,列印每一層的結點元素值,且每層訪問順序是從左到右。
分析
題目要求的廣義表輸入,可以聯絡括號匹配。通過層數來將節點分類儲存,既能夠適應廣義表,又能夠直接層次遍歷。
#include <iostream> #include <cstdio> #include <vector> #include <string> #include <algorithm> using namespace std; const int MAXN = 1e5; string str; vector<int> tree[MAXN]; //tree[i]表示第i層(從0計數)的一串節點 int main(){ cin >> str; int dep = 0, maxdep = -1, sum = 0; for (int i = 0; i < (int)str.length(); i++){ if('0' <= str[i] && str[i] <= '9'){ /*注意,輸入數字不一定為個位數!*/ sum = sum * 10 + str[i] - '0'; } else{ if(sum > 0) tree[dep].push_back(sum); sum = 0; //重置sum if (str[i] == '(') dep++; else if (str[i] == ')') dep--; } maxdep = max(maxdep, dep); //記錄最大深度 } for (int i = maxdep; i >= 0; i--){ for(int j = 0; j < (int)tree[i].size(); j++) printf("%d ", tree[i][j]); printf("\n"); } return 0; }
2. 使用前序字串構建一個二叉樹,並中序遍歷這棵樹。
題意
使用前序字串構建一個二叉樹,並輸出這棵樹中序遍歷。字串使用“#”表示孩子為空的情況。eg: abd#g###ce##f##
分析
題目中的前序遍歷序列,與以往不同的是已經給定空節點。由此得到的序列與深搜方向基本一致(順序不一定完全吻合),一開始對字串向右遍歷,實際上就是往樹的左側鏈進行遍歷,一旦遍歷過程中遇到#
就立即轉向到其兄弟節點(即右節點),繼續深入搜尋。
#include <iostream> #include <cstdio> #include <vector> #include <string> #include <queue> #include <algorithm> using namespace std; const int MAXN = 1e5; string str; char tree[MAXN]; int Build(int pos, int rt){ tree[rt] = str[pos]; if(str[pos] == '#') { tree[rt] = str[pos]; return pos; } int last = Build(pos + 1, rt << 1); last = Build(last + 1, rt << 1 | 1); //回溯最新訪問到的字元 return last; } void dfs(int rt){ if(tree[rt] == '#' || tree[rt] == '\0') return; dfs(rt << 1); cout << tree[rt]; dfs(rt << 1 | 1); } int main(){ cin >> str; Build(0, 1); dfs(1); return 0; }
3. 求節點的哈夫曼的帶權路徑長度
題意
已知輸入一串正整數,正整數之間用空格鍵分開,請建立一個哈夫曼樹,以輸入的數字為葉節點,求這棵哈夫曼樹的帶權路徑長度。
分析
往上建樹的模擬過程中,對每一次節點合併得到的新節點權值進行累加,其實就是對帶權路徑累加
#include <iostream> #include <cstdio> #include <vector> #include <string> #include <queue> #include <algorithm> using namespace std; const int MAXN = 100; priority_queue< int, vector<int>, greater<int> > myque; int tot = 0; int main(){ int n; scanf("%d", &n); for (int i = 1; i <= n; i++){ int tmp; scanf("%d", &tmp); myque.push(tmp); } int sum = 0; while(myque.size() > 1){ int lc = myque.top(); myque.pop(); int rc = myque.top(); myque.pop(); myque.push(lc + rc); sum += (lc + rc); } printf("%d\n", sum); }