如有不對 不吝賜教
給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是「同構」的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a、b、g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。
現給定兩棵樹,請你判斷它們是否是同構的。
輸入格式:
輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出乙個非負整數n (≤10),即該樹的結點數(此時假設結點從0到n−1編號);隨後n行,第i行對應編號第i個結點,給出該結點中儲存的1個英文大寫字母、其左孩子結點的編號、右孩子結點的編號。如果孩子結點為空,則在相應位置上給出「-」。給出的資料間用乙個空格分隔。注意:題目保證每個結點中儲存的字母是不同的。
輸出格式:
如果兩棵樹是同構的,輸出「yes」,否則輸出「no」。
輸入樣例1(對應圖1):
8a 1 2
b 3 4
c 5 -
d - -
e 6 -
g 7 -
f - -
h - -
8g - 4
b 7 6
f - -
a 5 1
h - -
c 0 -
d - -
e 2 -
輸出樣例1:
yes輸入樣例2(對應圖2):
8b 5 7
f - -
a 0 3
c 6 -
h - -
d - -
g 4 -
e 1 -
8d 6 -
b 5 -
e - -
h - -
c 0 2
g - 3
f - -
a 1 4
輸出樣例2:
no本來一開始是想用樹來解決的,但是腦子一熱就放棄了這個做法(其實這個方法特別的簡單,不過可能是那段時間寫樹的題目寫多了,就不想再用樹的做法),於是我選擇了使用靜態陣列來模擬樹的做法(歸根到底還是回到了樹)
首先 我用兩個26的陣列來表示兩棵樹分別使用的字母(因為不確定使用的一定是前n個大寫字母) 然後在用兩個陣列來分別表示每棵樹的每個節點的根節點(這句話繞口了點,但是這基本上是並查集的思想).
接下來就是用記錄每個節點的字元,這裡要記錄它的正向索引和逆向索引,以便後面對每個節點進行比較。
在這裡,不好直接比較每個字元在樹中的位置(一是因為我們使用的是靜態陣列來模擬樹,二是同構的時候將樹的左右節點進行了交換,節點的編號會不同),我選擇去比較它們父節點的字元
這裡解釋一下為什麼比較父節點的字元:
1.根據題目,同構樹的構成是通過交換左右節點來完成的,無論左右子樹內部怎麼變化,這兩個左右子樹的父節點始終是一樣的。
2.這剛好就利用上了我們記錄父節點的陣列,就沒必要再去生成乙個記錄子節點的陣列了(如果真這樣做,還不如去建棵樹).
下面給出**:
#include
intmain
(void
)//記錄父節點以及每個節點的字母
short n2;
scanf
("%hd"
,&n2)
;short father2[n2]
;char data2[n2]
;for
(i=0
;i) father2[i]
=i;if
(n1!=n2)
flag=0;
else
for(i=
0;i<
26;i++
)//說明出現的字元不同
if(data1[father1[node1[i]]]
!=data2[father2[node2[i]]]
)}}if
(flag)
printf
("yes");
else
printf
("no");
return0;
}// 樹是否同構的判別就是父節點是否相同
PTA資料結構與演算法題目集 中文 7 3
給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a b g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1 圖2現給定兩棵樹,請你判斷它們是否是同構的。輸入給出2棵二叉樹樹的資訊。對...
資料結構與演算法 7 3 樹的同構 25分
現給定兩棵樹,請你判斷它們是否是同構的。輸入格式 輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出乙個非負整數n 10 即該樹的結點數 此時假設結點從0到n 1編號 隨後n行,第i行對應編號第i個結點,給出該結點中儲存的1個英文大寫字母 其左孩子結點的編號 右孩子結點的編號。如果孩子結點為空...
資料結構與演算法練習 樹1 樹的同構(PTA)
題目 給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。現給定兩棵樹,請你判斷它們是否是同構的。輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出乙個非負整數n 10 即該樹的結點數 此時假設結點從0到n 1編號 隨後n行,第i行對應編號第i個結點...