03 樹1 樹的同構 25 分

2021-09-29 23:29:15 字數 4483 閱讀 3582

給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是「同構」的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a、b、g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。

現給定兩棵樹,請你判斷它們是否是同構的。

輸入格式:

輸入給出2棵二叉樹樹的資訊。對於每棵樹,首先在一行中給出乙個非負整數n (≤10),即該樹的結點數(此時假設結點從0到n−1編號);隨後n行,第i行對應編號第i個結點,給出該結點中儲存的1個英文大寫字母、其左孩子結點的編號、右孩子結點的編號。如果孩子結點為空,則在相應位置上給出「-」。給出的資料間用乙個空格分隔。注意:題目保證每個結點中儲存的字母是不同的。

輸出格式:

如果兩棵樹是同構的,輸出「yes」,否則輸出「no」。

輸入樣例1(對應圖1):

8

a 12

b 34

c 5-

d --

e 6-

g 7-

f --

h --

8g -

4b 7

6f -

-a 5

1h -

-c 0

-d -

-e 2

-

輸出樣例1:

yes
輸入樣例2(對應圖2):

8

b 57

f --

a 03

c 6-

h --

d --

g 4-

e 1-

8d 6

-b 5

-e -

-h -

-c 0

2g -

3f -

-a 1

4

輸出樣例2:

no
本題基本步驟有兩步,分別是讀入兩顆樹判斷是否同構我判斷是否同構的思路是從根節點開始,如果兩棵樹在該節點的左右子節點分別相等,則按照先序遍歷的方式,依次遞迴執行此判斷,直到葉子結點,若該節點的左右子節點交換位置後分別相等,則將其交換位置,仍舊按照先序遍歷的方式遞迴判斷,否則便返回0,代表不是同構。

我們首先定義樹的資料結構,採用靜態鍊錶,也就是陣列儲存

typedef

struct tnode* tree;

struct tnode

t1[11

],t2[11]

;

讀入兩棵樹的**如下:

int

initilaizetree

(tree t,

int*nn)

int root;

scanf

("%d"

,&n)

;*nn = n;

for(i =

0; i < n; i++)if

(r ==

'-')

t[i]

.right =10;

//使用t[10]代替空節點

else

}

這裡我們對於每乙個結點,當其子節點為空時,便讓他指向t[10]

t[10]的資料如下

t1[10]

.data =

'*';

//*代替null值

t1[10]

.left =10;

t1[10]

.right =10;

t2[10]

.data =

'*';

t2[10]

.left =10;

t2[10]

.right =

10;

這樣做的好處是有利於接下來判斷是否同構函式的編寫這樣之後我們的樹變成的下面的樣子

對於每乙個葉子結點,它的left和right都會指向*,即t[10] (未在圖中畫出),我們便可將此作為函式的出口,返回1代表此子樹是同構的。

我們引入t[10]可以讓所有的結點都有兩個子節點,這樣就迴避了對只有單個子節點情況的判斷,使我們的函式編寫起來更簡單

判斷同構函式如下

int

issimilarity

(tree t1,

int root1, tree t2,

int root2)

elseif(

((t1[root1]

.left ==10)

&&(t1[root1]

.right ==10)

)&&!(

(t2[root2]

.left ==10)

&&(t2[root2]

.right ==10)

))//一棵樹子節點都為null而另一顆樹不是

return0;

elseif(

!((t1[root1]

.left ==10)

&&(t1[root1]

.right ==10)

)&&((t2[root2]

.left ==10)

&&(t2[root2]

.right ==10)

))//一棵樹子節點都為null而另一顆樹不是

return0;

else

if(t1[t1[root1]

.left]

.data == t2[t2[root2]

.left]

.data &&

t1[t1[root1]

.right]

.data == t2[t2[root2]

.right]

.data)

//兩棵樹左右子節點分別相等

else

if(t1[t1[root1]

.left]

.data == t2[t2[root2]

.right]

.data &&

t1[t1[root1]

.right]

.data == t2[t2[root2]

.left]

.data)

//兩棵樹左右子節點交換位置後相等

else

return0;

}

完整**如下

#include

#include

typedef

struct tnode* tree;

struct tnode

t1[11

],t2[11]

;int

initilaizetree

(tree t,

int*nn)

int root;

scanf

("%d"

,&n)

;*nn = n;

for(i =

0; i < n; i++)if

(r ==

'-')

t[i]

.right =10;

//使用t[10]代替空節點

else

}int

issimilarity

(tree t1,

int root1, tree t2,

int root2)

else

if(t1[t1[root1]

.left]

.data == t2[t2[root2]

.right]

.data &&

t1[t1[root1]

.right]

.data == t2[t2[root2]

.left]

.data)

//兩棵樹左右子節點交換位置後相等

else

return0;

}int

main()

else

if(root1 ==-1

&& root2 ==-1

)//兩顆空樹是同構

else

if(t1[root1]

.data != t2[root2]

.data)

//兩個根結點值不同,不是同構

else

return0;

}

03 樹1 樹的同構 25分

03 樹1 樹的同構 25分 給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a b g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1現給定兩棵樹,請你判斷它們是否是同構的。輸入給...

03 樹1 樹的同構(25 分)

圖1 10 即該樹的結點數 此時假設結點從0到n 1編號 隨後 n行,第 i行對應編號第 i個結點,給出該結點中儲存的1個英文大寫字母 其左孩子結點的編號 右孩子結點的編號。如果孩子結點為空,則在相應位置上給出 給出的資料間用乙個空格分隔。注意 題目保證每個結點中儲存的字母是不同的。8 a 1 2 ...

03 樹1 樹的同構 (25 分)

給定兩棵樹t1和t2。如果t1可以通過若干次左右孩子互換就變成t2,則我們稱兩棵樹是 同構 的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點a b g的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1 圖2現給定兩棵樹,請你判斷它們是否是同構的。輸入給出2棵二叉樹樹的資訊。對...