1. 程式人生 > >算法入門經典-第五章 例題6-10 下落的樹葉

算法入門經典-第五章 例題6-10 下落的樹葉

說明 height 遍歷 ring ons 葉子 技巧 iostream 表示

給一顆二叉樹,每個節點都有一個水平位置:左子結點在它的左邊一個單位,右子節點在右
邊一個單位。從左向右輸出每個水平位置的所有節點的權值之和。如圖所示,從左到右的三
個位置權和分別為 7,11,3,按照遞歸(先序)方式輸入,用-1 表示空樹。

Sample Input

5 7 -1 6 -1 -1 3 -1 -1

8 2 9 -1 -1 6 5 -1 -1 12 -1 -1 3 7 -1 -1 -1 -1


Sample Output

Case 1: 7 11 3

Case 2: 9 7 21 15

題目的意思是讓我們從左到右輸出樹葉下落的數量

舉例說明一下:

8 2 9 -1 -1 6 5 -1 -1 12 -1 -1 3 7 -1 -1 -1 -1


二叉樹結構為:

技術分享

技術分享

#include<cstring>
#include<iostream>
using namespace std;

const int maxn = 200;
int sum[maxn];
//怎麽建立二叉樹,然後在進行一系列復雜的處理,說實話,這個題真沒有想到有這麽巧妙的技巧,直接采用先序遍歷的方式,先對頭結點做處理.考慮到題目中的意思數組長度最長為80,一開始,我們從下標為40的執行,array[40]=8,然後遞歸執行左子樹,接著是右子樹。整體思路是這樣,執行左子樹的時候,傳入的下標-1,判斷當前左子樹的頭結點的值,然後繼續遞歸調用其左右子樹。。。
//讀入並建立一棵樹,樹根的水平位置為p循環每棵樹 
void build(int p) { int v; cin>>v; if(v==-1) return;//讀到-1停止 sum[p]+=v; //建立左右子樹 build(p-1); build(p+1); } bool init(){ int v; cin>>v; if(v==-1) return false;//要不然循環每個case memset(sum,0,sizeof(sum)); int pos=maxn/2;//樹根的水平位置 sum[pos]=v; //先序遍歷,先左子樹,再右子樹
build(pos - 1); build(pos + 1); } int main() { int kase = 0; while(init()) { int p = 0; while(sum[p] == 0) p++; // 找最左邊的葉子 // 開始輸出。因為要避免行末多余空格,所以稍微麻煩一點 cout << "Case " << ++kase << ":\n" << sum[p++]; while(sum[p] != 0) { cout << " " << sum[p]; p++; } cout << "\n\n"; } return 0; }

算法入門經典-第五章 例題6-10 下落的樹葉