數據結構與算法題目集(中文) 7-3 樹的同構 (25分)

在這裏插入圖片描述

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 -
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

題解:次一個節點並不是根節點,根節點需要自己判斷,可以一邊建樹一邊判斷,具體的註釋在代碼中。建樹不難,判斷那部分較難,很多人可能用的是指針形式,後面通過指針交換左右子樹進行判斷,哪種方法極容易錯,而且麻煩,可以直接根據是否爲空,不爲空數值是否相等進行判斷

c++:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define NULL -1
struct node
{
    char ch;
    int left;
    int right;
} tree1[100], tree2[100];
bool book[100];
//建樹
int build(struct node tree[])
{
    int n;
    int book[110];
    char data, l, r;
    memset(book, 0, sizeof(book)); //將所有點初始化
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        getchar(); //吸收回車
        scanf("%c", &data);
        getchar(); //吸收空格
        scanf("%c", &l);
        getchar(); //吸收空格
        scanf("%c", &r);
        //		printf("%c %c %c\n",data,l,r);
        tree[i].ch = data;
        //判斷左右子樹是否存在並標記
        if (l == '-')
        {
            tree[i].left = NULL;
        }
        else
        {
            tree[i].left = l - '0';
            book[l - '0'] = 1;
        }
        if (r == '-')
        {
            tree[i].right = NULL;
        }
        else
        {
            tree[i].right = r - '0';
            book[r - '0'] = 1;
        }
    }
    int root = NULL; //這裏一定要賦值爲NULL
    for (int i = 0; i < n; i++)
    {
        if (!book[i])
        {
            root = i;
        }
    }
    return root;
}
bool judge(int root1, int root2)
{
    if (root1 == NULL && root2 == NULL)
    {                //判斷根節點是否都爲空
        return true; //都爲空則相同
    }
    if (root1 == NULL && root2 != NULL || root1 != NULL && root2 == NULL)
    {
        return false; //一個根節點爲空另外一個不爲空則爲假
    }
    if (tree1[root1].ch != tree2[root2].ch)
    {
        return false; //兩棵樹根節點都存在,但數值不同則爲假
    }
    if (tree1[tree1[root1].left].ch == tree2[tree2[root2].left].ch)
    {
        //如果左子樹的值相等則判斷右子樹
        return judge(tree1[root1].right, tree2[root2].right);
    }
    else
    {
        //否則判斷是否第二棵樹是在第一課樹左右子樹調換之後得到的
        return judge(tree1[root1].left, tree2[root2].right) && judge(tree1[root1].right, tree2[root2].left);
    }
}
int main()
{
    //	freopen("input.txt","r",stdin);
    int root1 = build(tree1);
    int root2 = build(tree2);
    if (judge(root1, root2))
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}

c:

#include <stdio.h>
#include <string.h>
#define NULL -1
struct node
{
    int left, right;
    char data;
} tree1[100], tree2[100];
int book[1000];
int build(struct node tree[])
{
    int n, i, root;
    memset(book, 0, sizeof(book));
    char left, right;
    scanf("%d", &n);
    getchar();
    for (i = 0; i < n; i++)
    {
        scanf("%c %c %c\n", &tree[i].data, &left, &right);
        //		printf("%c %c %c\n",tree1[i].data,left,right);
        if (left == '-')
        {
            tree[i].left = NULL;
        }
        else
        {
            tree[i].left = left - '0';
            book[left - '0'] = 1;
        }
        if (right == '-')
        {
            tree[i].right = NULL;
        }
        else
        {
            tree[i].right = right - '0';
            book[right - '0'] = 1;
        }
    }
    root = NULL;
    for (i = 0; i < n; i++)
    {
        if (book[i] == 0)
        {
            root = i;
        }
    }
    return root;
}
int judge(int root1, int root2)
{
    if (root1 == NULL && root2 == NULL)
    {
        return 1;
    }
    if ((root1 == NULL && root2 != NULL) || (root1 != NULL && root2 == NULL))
    {
        return 0;
    }
    if (tree1[root1].data != tree2[root2].data)
    {
        return 0;
    }
    if (tree1[tree1[root1].left].data == tree2[tree2[root2].left].data)
    {
        return judge(tree1[root1].right, tree2[root2].right);
    }
    else
        return judge(tree1[root1].left, tree2[root2].right) && judge(tree1[root1].right, tree2[root2].left);
}
int main()
{
    //	freopen("input.txt","r",stdin);
    int root1, root2, i;
    root1 = build(tree1);
    root2 = build(tree2);
    //	for(i = 0;i < 8;i++)
    //	{
    //		printf("%c %d %d\n",tree1[i].data,tree1[i].left,tree1[i].right);
    //	 }
    //	 printf("\n");
    //	for(i = 0;i < 8;i++)
    //	{
    //		printf("%c %d %d\n",tree2[i].data,tree2[i].left,tree2[i].right);
    //	 }
    if (judge(root1, root2) == 1)
    {
        printf("Yes\n");
    }
    else
    {
        printf("No\n");
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章