二叉樹的表達
樹的遍歷
從根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,就是你贏,否則就是你的朋友贏。你挑戰了好幾回,結果一次也沒贏過,於是怒而撕破口袋,取出所有紙片,檢查自己是否真的有贏的可能性。請你編寫乙...