挑戰程式設計競賽 樹

2021-10-24 01:51:12 字數 3432 閱讀 9501

二叉樹的表達

樹的遍歷

從根r到結點x的路徑長度為x的深度(depth),結點x到葉結點的最大路徑長度成為結點x的

請編寫乙個程式,輸出給定有根樹t中各節點u的資訊。

採用「左子右兄弟表示法」:

1、結點u的父節點

2、結點u最左側的子結點

3、結點u右側緊鄰的兄弟結點

引用u.parent即可知道結點u的父結點,不存在父結點就是跟。不存在u.left的結點是葉子結點。不存在u.right的結點為最右側子結點。

#include

using

namespace std;

#define max 100005

#define nil -1

struct node

; node t[max]

;int n,d[max]

;/*列印*/

void

print

(int u)

cout<<

"]"<}/*遞迴求深度*/

intrec

(int u,

int p)

intmain()

}for

(i=0

;i)rec

(r,0);

for(i=

0;i)print

(i);

return0;

}

二叉樹t,請編寫乙個程式,輸出其各結點u的如下資訊:

1、u的結點編號

2、u的深度

3、u的父結點

4、u的高

5、u的兄弟結點

6、結點的種類

7、u子結點數

求二叉樹結點的高可以用遞迴法,如果左右子樹不為空,則高度加1,繼續向下進行。最後選擇左右子樹高度中的最大值作為二叉樹結點的高。

/*輸入:id left(左子樹) right(右子樹)

輸出:node id:parent=p,sibling=s,degree=d,depth=dep,height=h,type

*/#include

#define max 1000

#define nil -1

using

namespace std;

struct node

;node t[max]

;int n,d[max]

,h[max]

;//子樹的深度,子樹的高度

/*求深度(從根r到結點x的路徑長度為x的深度)*/

void

setdepth

(int u,

int d)

/*求高度(結點x到葉結點的最大路徑長度成為結點x的高)*/

intsetheight

(int u)

/*求兄弟結點*/

intgetsibling

(int u)

/*列印*/

void

print

(int u)

intmain()

for(i=

0;i(t[i]

.parent==nil) root=i;

setdepth

(root,0)

;setheight

(root)

;for

(i=0

;i)print

(i);

return0;

}

系統地訪問樹的所有結點:

1、按照結點、左子樹、右子樹前序遍歷

2、按照左子樹、結點、右子樹中序遍歷

3、按照左子樹、右子樹、結點後序遍歷

以preparse(u)為例,程式先訪問u,然後執行preparse(t[u].left)訪問u的左子樹,處理完成後執行preparse(t[u].right)訪問u的右子樹。

同理,只要改變print(u)的位置就可以實現不同的演算法。

/*輸入:id left right

輸出:preorder:

inorder:

postorder:

*/#include

#define max 10000

#define nil -1

struct node

;struct node t[max]

;int n;

/*前序遍歷*/

void

preparse

(int u)

/*中序遍歷*/

void

orderparse

(int u)

/*後序遍歷*/

void

postparse

(int u)

intmain()

//找到根

for(i=

0;i(t[i]

.parent==nil) root=i;

printf

("preorder:");

preparse

(root)

;printf

("\n");

printf

("inorder:");

orderparse

(root)

;printf

("\n");

printf

("postorder:");

postparse

(root)

;printf

("\n");

return0;

}

根據已知樹的前序遍歷結果和中序遍歷結果,得到後序遍歷結果。

preorder按照根—>左子樹—>右子樹的順序遞迴遍歷,inorder按照左子樹—>根—>右子樹的順序遞迴遍歷。首先按preorder遍歷的順序依次訪問各結點。訪問過程中,我們能通過in得知各子樹內inorder遍歷的順序,從而重建以當前結點c為根的左子樹和右子樹。

比如當前結點為1(前序遍歷),其在in中的位置(中序遍歷)為3 2 5 4 6 8 7 9,那麼當前樹的根就是1,左右子樹為 3 2 5 4 6和8 7 9。依次類推。

#include

#include

#include

#include

using

namespace std;

int n,pos;

vector<

int> pre,in,post;

void

rec(

int l,

int r)

void

solve()

cout<}int

main()

for(i=

0;i)solve()

;return0;

}

挑戰程式設計競賽(3)

給定整數a1,a2,an,判斷是否可以從中選出若干數,使他們的和恰好為k。1 n 20 1e8 ai 1e8 1e8 k 1e8 樣例1input 4 1 2 4 7 13 output yes 13 2 4 7 樣例2input 4 1 2 4 7 15 output no dfs include...

挑戰程式設計競賽 硬幣遊戲

首先明確此為0和博弈問題,我們始終以ali cealice alic e的觀點來看待問題。定義ali cealice alic e贏為可解.因此我們採用記憶化搜尋,整個搜尋空間最多為o x p o xp o xp 便可以解決此問題。include includeusing namespace std...

ACM挑戰程式設計競賽1 1抽籤

試題描述 你的朋友提議玩乙個遊戲 將寫有數字的n 個紙片放入口袋中,你可以從口袋中抽取4 次紙片,每次記下紙片上的數字後都將其放回口袋中。如果這4 個數字的和是m,就是你贏,否則就是你的朋友贏。你挑戰了好幾回,結果一次也沒贏過,於是怒而撕破口袋,取出所有紙片,檢查自己是否真的有贏的可能性。請你編寫乙...