1. 程式人生 > >PTA 5-10 樹的同構

PTA 5-10 樹的同構

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。


圖1


圖2

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

輸入格式:

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

輸出格式:

如果兩棵樹是同構的,輸出“Yes”,否則輸出“No”。

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

8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -

輸出樣例1:

Yes

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

8
B 5 7
F - -
A 0 3
C 6 -
H - -
D - -
G 4 -
E 1 -
8
D 6 -
B 5 -
E - -
H - -
C 0 2
G - 3
F - -
A 1 4

輸出樣例2:

No

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct treeInf{//存節點資訊,下標就代表了節點編號
	char data;
	int left;
	int right;
};
struct treeNode{//樹的節點
	int number;//節點編號,對應節點資訊
	char element;
	struct treeNode* left;
	struct treeNode* right;
};
struct treeNode* CreateTree(){//讀取資料,建樹
	int n;//節點數目
	int start;//根節點編號
	cin>>n;
	if(!n)//空樹
		return NULL;
	getchar();
	struct treeInf treeTemp[n];//臨時讀取節點資訊
	struct treeNode* queue[n+10];//佇列用於樹的實現過程
	int book[n];//用於找根節點,根節點不會作為任何一個節點的左右兒子
	memset(book,0,sizeof(book));
	int head=0,tail=0;
	for(int i=0;i<n;i++){//讀資料
		char temp;
		cin>>temp;
		treeTemp[i].data=temp;
		getchar();
		cin>>temp;
		if(temp!='-'){
			treeTemp[i].left=temp-'0';
			book[temp-'0']=1;
		}
	    else
	    	treeTemp[i].left=-1;
	    getchar();
	    cin>>temp;
		if(temp!='-'){
			treeTemp[i].right=temp-'0';
			book[temp-'0']=1;
		}
	    else
	    	treeTemp[i].right=-1;
	}
    for(int i=0;i<n;i++){//找 根節點
    	if(!book[i]){
    		start=i;
    		break;
    	}
    }
	queue[tail]=(struct treeNode*)malloc(sizeof(struct treeNode));//根節點入隊
	queue[tail]->number=start;
	queue[tail]->element=treeTemp[start].data;
	tail++;
	while(head<tail){
		struct treeNode* temp;
		if(treeTemp[queue[head]->number].left!=-1){//左兒子入隊
			temp=(struct treeNode*)malloc(sizeof(struct treeNode));
			temp->number=treeTemp[queue[head]->number].left;
			temp->element=treeTemp[temp->number].data;
			queue[head]->left=temp;
			queue[tail]=temp;
			tail++;
		}
		else
			queue[head]->left=NULL;
		if(treeTemp[queue[head]->number].right!=-1){//右兒子入隊
			temp=(struct treeNode*)malloc(sizeof(struct treeNode));
			temp->number=treeTemp[queue[head]->number].right;
			temp->element=treeTemp[temp->number].data;
			queue[head]->right=temp;
			queue[tail]=temp;
			tail++;
		}
		else
			queue[head]->right=NULL;
		head++;
	}
    return queue[0];
}
int Judge(struct treeNode* binTree1,struct treeNode* binTree2){//思路:遞迴判斷
	int result1,result2;
	if(binTree1==NULL&&binTree2==NULL)//兩(子)樹均為空,滿足同構
		return 1;
	if(binTree1->element!=binTree2->element)//兩(子)樹當前節點值不同,不同構
		return 0;
	if(!binTree1->left&&!binTree1->right&&!binTree2->left&&!binTree2->right)//1樹左兒子空,右兒子空 2樹左兒子空,右兒子空
		return 1;
	else if(binTree1->left&&!binTree1->right&&binTree2->left&&!binTree2->right){//1樹左兒子非空,右兒子空 2樹左兒子非空,右兒子空
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
    else if(!binTree1->left&&binTree1->right&&!binTree2->left&&binTree2->right){//1樹左兒子空,右兒子非空 2樹左兒子空,右兒子非空
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
	else if(binTree1->left&&!binTree1->right&&!binTree2->left&&binTree2->right){//1樹左兒子非空,右兒子空 2樹左兒子空,右兒子非空
		binTree2->left=binTree2->right;
		binTree2->right=NULL;
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
	else if(!binTree1->left&&binTree1->right&&binTree2->left&&!binTree2->right){//1樹左兒子空,右兒子非空 2樹左兒子非空,右兒子空
		binTree2->right=binTree2->left;
		binTree2->left=NULL;
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
	//兩個樹的左右兒子均存在,且值相同
	else if(binTree1->left&&binTree1->right&&binTree2->left&&binTree2->right&&binTree1->left->element==binTree2->left->element&&binTree1->right->element==binTree2->right->element){
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
	//兩個樹的左右兒子均存在,且左右子樹值對調
	else if(binTree1->left&&binTree1->right&&binTree2->left&&binTree2->right&&binTree1->left->element==binTree2->right->element&&binTree1->right->element==binTree2->left->element){
		struct treeNode* temp=binTree2->left;
		binTree2->left=binTree2->right;
		binTree2->right=temp;
		result1=Judge(binTree1->left,binTree2->left);
		result2=Judge(binTree1->right,binTree2->right);
		return result1&&result2?1:0;
	}
	else//其他情況,肯定不滿足
		return 0;
}
void preOrder(struct treeNode* tree)
{
	if(tree==NULL)
		return;
    cout<<tree->number<<' '<<tree->element<<'\n';
    if(tree->left)
    	preOrder(tree->left);
    if(tree->right)
    	preOrder(tree->right);
}
int main(){
	struct treeNode* binTree1;
	struct treeNode* binTree2;
	binTree1=CreateTree();
	//preOrder(binTree1);
	binTree2=CreateTree();
	//preOrder(binTree2);
	int flag=Judge(binTree1,binTree2);
	if(flag)
		cout<<"Yes\n";
	else
		cout<<"No\n";
	return 0;
}


相關推薦

PTA 5-10

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1 圖2 現給定兩棵樹,請你判斷它們是否是同構的。 輸入格式:

PTA 5-10 的遍歷 (25分)】+ 二叉

5-10 樹的遍歷 (25分) 給定一棵二叉樹的後序遍歷和中序遍歷,請你輸出其層序遍歷的序列。這裡假設鍵值都是互不相等的正整數。 輸入格式: 輸入第一行給出一個正整數NN(\le 30≤30),是二叉樹中結點的個數。第二行給出其後序遍歷序列。第三行給出

【BZOJ3162】獨釣寒江雪 +DP

eight pri 相同 題解 con oid src str mil 【BZOJ3162】獨釣寒江雪 題解:先進行樹hash,方法是找重心,如果重心有兩個,則新建一個虛點將兩個重心連起來,新點即為新樹的重心。將重心當做根進行hash,hash函數不能太簡單,

BZOJ4337: BJOI2015 (hash )

題意 題目連結 Sol 樹的同構問題,直接拿hash判一下,具體流程大概是這樣的: 首先轉化為有根樹,預處理出第\(i\)棵樹以\(j\)為根時的hash值。 那麼兩個樹同構當且僅當把兩棵樹的hash陣列排完序後完全一致(感性理解一下) /* */ #include<bits/stdc++

PTA 5-10 說反話-加強版 【】

5-10 說反話-加強版   (20分) 給定一句英語,要求你編寫程式,將句中所有單詞的順序顛倒輸出。 輸入格式: 測試輸入包含一個測試用例,在一行內給出總長度不超過500 000的字串。字串

有根 (Hash)

crf 出生的第二秒 1 Description crf 是一個天才。 他出生的第二秒,往窗外望了一眼,看到了窗外的樹林。 他發現這片樹林非常有趣,因為它只有一排樹,從左到右依次排列。 天才的crf 馬上就把真實的樹的結構抽象成為了圖論中的樹(即任意兩

如何判斷兩顆二叉

#define MaxTree 10 #define ElementType char #define Tree int #define Null -1 struct TreeNode{ElementType Element; Tree Left;Tree Righ

PTA資料結構 5-3

題目:   給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1

PTA 資料結構與演算法題目集(中文)5-3 (25分)

#include <stdio.h> #include <string.h> /* 題目以26個大寫字母為結點值,可以建立一個26*2的二維陣列 表示結點以及結點的左右結點 若只有一個結點,則判斷兩根是否相同 若有多節點,則先將前一棵樹的結點的左右結

7-10 (25 分)

lib tps ring pan ges 輸出 ble ram 技術 給定兩棵樹T1和T2。如果T1可以通過若幹次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩

PTA (25 分)

其中 content turn 不同 是否 std itl ng- class 7-1 樹的同構(25 分) 給定兩棵樹T1和T2。如果T1可以通過若幹次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、

03-1 -PTA

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。     圖1 圖2 現

7-5 (25 分)

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1 圖2 現給定兩棵樹,請你判斷它們是否

PTA 7-1 (25 分)

#include using namespace std; typedef struct Node { char ch; // 節點所儲存的字母 char left;// left - '0' 即為此節點左兒子在陣列中的下標 char right; }; Node tree[

5-3 (25分)

5-3 樹的同構   (25分) 給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A

7-5

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1圖2現給定兩棵樹,請你判斷它們是否是同構的。輸入格式

7-10 (25 point(s))

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1 圖2 現給定兩棵樹,請你判斷它們是否是同構的。 輸入格式: 輸入給出2棵二叉

PTA練習題---

問題描述:給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。圖1圖2現給定兩棵樹,請你判斷它們是否是同構的

PTA || 03-1

給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 圖1 圖2 現給定兩棵樹,請你判斷

PTA——03-1 (25 分)【java語言實現】

題目 給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。 現給定兩棵樹,請你判斷