1. 程式人生 > >04-樹4 是否同一棵二叉搜尋樹 (25分)

04-樹4 是否同一棵二叉搜尋樹 (25分)

給定一個插入序列就可以唯一確定一棵二叉搜尋樹。然而,一棵給定的二叉搜尋樹卻可以由多種不同的插入序列得到。例如分別按照序列{2, 1, 3}和{2, 3, 1}插入初始為空的二叉搜尋樹,都得到一樣的結果。於是對於輸入的各種插入序列,你需要判斷它們是否能生成一樣的二叉搜尋樹。

輸入格式:

輸入包含若干組測試資料。每組資料的第1行給出兩個正整數NN (1010)和LL,分別是每個序列插入元素的個數和需要檢查的序列個數。第2行給出NN個以空格分隔的正整數,作為初始插入序列。最後LL行,每行給出NN個插入的元素,屬於LL個需要檢查的序列。

簡單起見,我們保證每個插入序列都是1到NN的一個排列。當讀到N

N為0時,標誌輸入結束,這組資料不要處理。

輸出格式:

對每一組需要檢查的序列,如果其生成的二叉搜尋樹跟對應的初始序列生成的一樣,輸出“Yes”,否則輸出“No”。

輸入樣例:

4 2
3 1 4 2
3 4 1 2
3 2 4 1
2 1
2 1
1 2
0

輸出樣例:

Yes
No
No
主要思路:
1、構建樹的方式,我採用的方式是vector的下標為該結點的值,結點中存放該結點的左右孩子在vector中的下標
2、使用迭代的方式構建樹,每輸入一個新結點後,4種情況的判斷(見程式碼)
3、比較兩樹是否相等,通過比較兩樹中值(vector下標)相同的兩個的結點的左右孩子是否相同,每一對對應結點都相同則兩棵樹相同
#include<iostream>
#include<vector>

using namespace std;

#define Max_Node 11
#define END -1

typedef struct node
{
    int left;
    int right;
}Node;

void Initialize_Tree(vector<Node>& Tree,int N)//初始化樹
{
    for (int i=1; i<=N; ++i)
    {
        Tree[i].left=END;
        Tree[i].right=END;
    }
}

void Build_Tree(vector<Node>& Tree,int N)//讀取輸入並建樹
{
    int value,flag=0,root=0,pre=0;
    while (N--)
    {
        cin>>value;
        if (flag==0)//讀到的第一個結點為根結點,記錄下來
        {
            root=value;
            pre=root;
            flag=1;
        }else
        {
            while (1)
            {
                if (value>pre && Tree[pre].right!=END)//當前輸入值比訪問的上一個結點pre(pre最初為根結點)大,且pre有右孩子
                {
                    pre=Tree[pre].right;
                }
                if (value>pre && Tree[pre].right==END)//當前輸入值比訪問的上一個結點pre(pre最初為根結點)大,且pre無右孩子
                {
                    Tree[pre].right=value;
                    pre=root;//下一次輸入數字也從根結點開始比較
                    break;
                }
                if (value<pre && Tree[pre].left!=END)//當前輸入值比訪問的上一個結點pre(pre最初為根結點)小,且pre有左孩子
                {
                    pre=Tree[pre].left;
                }
                if (value<pre && Tree[pre].left==END)//當前輸入值比訪問的上一個結點pre(pre最初為根結點)小,且pre無左孩子
                {
                    Tree[pre].left=value;
                    pre=root;//下一次輸入數字也從根結點開始比較
                    break;
                }
            }
        }
    }
}

bool Compare_Tree(vector<Node> Tree1,vector<Node> Tree2,int N)//比較兩棵樹的每一個結點的左右孩子結點是否相等
{
    int i=1;
    for (; i<=N; ++i)
    {
        if (!(Tree1[i].left==Tree2[i].left && Tree1[i].right==Tree2[i].right))
        {
            return false;
        }
    }
    return true;
}

int main()
{
    int N,L;
    int flag=0;
    while (1)
    {
        cin>>N;
        if (N==0)
        {
            break;
        }
        cin>>L;
        vector<vector<Node> > vec(L,vector<Node>(Max_Node));
        vector<Node> Tree(Max_Node);
        Initialize_Tree(Tree, N);
        for (int i=0; i<L; ++i)
        {
            Initialize_Tree(vec[i], N);
        }
        Build_Tree(Tree, N);
        for (int i=0; i<L; i++)
        {
            Build_Tree(vec[i], N);
            if (Compare_Tree(Tree, vec[i], N))
            {
                if (flag==0)
                {
                    flag=1;
                    cout<<"Yes";
                }else
                {
                    cout<<'\n'<<"Yes";
                }
            }else
            {
                if (flag==0)
                {
                    flag=1;
                    cout<<"No";
                }else
                {
                    cout<<'\n'<<"No";
                }
            }
        }
    }
    
    return 0;
}