zoukankan      html  css  js  c++  java
  • 04-树4 是否同一棵二叉搜索树

         给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。

    输入格式:

    输入包含若干组测试数据。每组数据的第1行给出两个正整数NN (le 1010)和LL,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出NN个以空格分隔的正整数,作为初始插入序列。最后LL行,每行给出NN个插入的元素,属于LL个需要检查的序列。

    简单起见,我们保证每个插入序列都是1到NN的一个排列。当读到NN为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.分别建两棵搜索树的判别方法
    2.不建树的判别方法
    3. 建一棵树,再判别其他序列是否与该树一致

    求解思路
    1. 搜索树表示
    2. 建搜索树T
    3. 判别一序列是否与搜索树T一致

    /*!
     * file 04-树4 是否同一棵二叉搜索树.cpp
     *
     * author ranjiewen
     * date 三月 2017
     *
     * 
     */
    
    //两个序列是否对应相同搜索树的判别
    //1.分别建两棵搜索树的判别方法
    //2.不建树的判别方法
    //3. 建一棵树,再判别其他序列是否与该树一致
    
    #include <stdio.h>
    #include <stdlib.h>
    typedef int Status;  //函数类型
    typedef int ElementType;
    
    typedef struct TreeNode* BSTree;
    struct TreeNode
    {
        ElementType Data;
        BSTree Left;
        BSTree Right;
        int Flag;   //被访问为1,否则0
    };
    
    BSTree NewNode(ElementType data);
    BSTree Insert(BSTree T, ElementType data);
    BSTree MakeTree(int N);
    bool Check(BSTree T,ElementType data);
    int Judge(BSTree T);
    void ResetT(BSTree T);
    void FreeT(BSTree T);
    
    BSTree NewNode(ElementType data)
    {
        BSTree root = (BSTree)malloc(sizeof(struct TreeNode));
        root->Data = data;
        root->Left = NULL;
        root->Right = NULL;
        root->Flag = 0;
        return root;
    }
    
    BSTree Insert(BSTree root, ElementType data)
    {
        if (root==NULL)
        {
            root = NewNode(data);
        }
        else
        {
            if (root->Data < data)
            {
                root->Right = Insert(root->Right, data);
            }
            else
            {
                root->Left = Insert(root->Left, data);
            }
        }
        return root;
    }
    
    BSTree MakeTree(int N)
    {
        BSTree T;
        ElementType data;
        scanf("%d", &data);
        T = NewNode(data);
        for (int i = 1; i < N; i++)
        {
            scanf("%d", &data);
            T = Insert(T, data);
        }
        return T;
    }
    
    //将另一棵树的结点依次在一颗二叉树上搜索,找到后标记;当搜索过程中有未被标记的结点,说明两棵树不一样
    bool Check(BSTree T, ElementType data)
    {
        if (T->Flag)
        {
            if (data<T->Data)
            {
                return Check(T->Left, data);
            }
            else
            {
                return Check(T->Right, data);
            }
        }
        else
        {
            if (data==T->Data)
            {
                T->Flag = 1;
                return true;
            }
            else
            {
                return false; //结点不一致
            }
        }
    }
    
    int Judge(BSTree T, int N)
    {
        ElementType data;
        int flag = 0; //0代表目前乃一致,1代表已经不一致
        scanf("%d", &data);
        if (data!=T->Data) //判断根结点是否一致
        {
            flag = 1; //不一致的情况下也要把后面的结点输入后才做判断
        }
        else T->Flag = 1;
        for (int i = 1; i < N; i++)
        {
            scanf("%d", &data);
            if ((!flag)&&(!Check(T,data)))
            {
                flag = 1;
            }
        }
        if (flag)
        {
            return 0;
        }
        else 
            return 1;
    }
    
    void ResetT(BSTree T) //清除T中各结点的flag标记
    {
        if (T->Left)
        {
            ResetT(T->Left);
        }
        if (T->Right)
        {
            ResetT(T->Right);
        }
        T->Flag = 0;
    }
    
    void FreeT(BSTree T) //释放T的空间
    {
        if (T->Left)
        {
            FreeT(T->Left);
        }
        if (T->Right)
        {
            FreeT(T->Right);
        }
        free(T);
    }
    
    int main()
    {
        int N;
        int L;
        BSTree T;
        scanf("%d", &N);
        while (N)  //可以多次输入测试
        {
            scanf("%d", &L); //需要检查的序列个数
            T = MakeTree(N); //输入N个元素创建树
            for (int i = 0; i < L;i++) //对每个序列操作
            {
                if (Judge(T, N)) //依次输入N个元素,每个元素都进行标记判断
                {
                    printf("Yes
    ");
                }
                else
                {
                    printf("No
    ");
                }
                ResetT(T);
            }
            FreeT(T);
            scanf("%d", &N);
        }
    }



  • 相关阅读:
    摄影基础知识(二)
    std::bind
    摄影网站汇总
    std::function
    常用路径说明
    摄影基础知识(一)
    JavaScript 箭头函数:适用与不适用场景
    软帝学院:Java实现的5大排序算法
    软帝学院:用Java编写计算器,代码展示!
    windows环境下运行java的脚本
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/6654173.html
Copyright © 2011-2022 走看看