• 04-树4 是否同一棵二叉搜索树 (25分)


    题目描述

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

    输入格式

    输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
    简单起见,我们保证每个插入序列都是1到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
    

    解题思路

    对于每一波(输入样例有两波),先将N和L读进来,然后根据第一个序列构建二叉搜索树,最后将接下来的序列与该树做比较,判断是否是同一棵二叉搜索树。那么现在主要有两个问题,一个是通过序列构建二叉搜索树,另一个是将序列与已有的树做比较。对于第一个问题,先把第一个值作为根,然后读取后面的值。若待插入的值比当前结点的值小,则插入在左子树上;若待插入的值比当前结点的值大,则插入在右子树上,显然这可以通过一个递归函数实现。对于第二个问题,可以在树的结点中添加一个标志,当标志为1时代表该结点已经比较过了,当标志为0时代表该结点还没比较过。因此每读取一个值的时候就调用一次比较函数。该函数从根节点开始比较,在当前结点标志为0的情况下,若结点值等于读取值,则说明比较成功,否则比较失败;在当前结点标志为1的情况下,若读取值大于结点值则比较结点的右子树,若读取值小于结点值则比较结点的左子树,若相等则比较失败(因为结点值唯一),显然这也可以通过一个递归函数实现。

    代码

    #include <stdio.h>
    #include <stdlib.h>
    
    struct TreeNode {
        int data;
        int flag;
        struct TreeNode *left;
        struct TreeNode *right;
    };
    typedef struct TreeNode *Tree;
    
    Tree makeTree(int n);
    Tree newNode(int data);
    Tree insert(Tree root, int data);
    int judge(Tree root, int n);
    int check(Tree root, int data);
    void reset(Tree root);
    void freeTree(Tree root);
    
    int main() {
        int N, L;
        Tree root;
        scanf("%d", &N);
        while (N) {
            scanf("%d", &L);
            root = makeTree(N);
            for (int i = 0; i < L; i++) {
                if (judge(root, N)) printf("Yes
    ");
                else printf("No
    ");
                reset(root);
            }
            freeTree(root);
            scanf("%d", &N);
        }
        return 0;
    }
    
    Tree makeTree(int n) {
        Tree root;
        int data;
        scanf("%d", &data);
        root = newNode(data);
        for (int i = 1; i < n; i++) {
            scanf("%d", &data);
            root = insert(root, data);
        }
        return root;
    }
    
    Tree newNode(int data) {
        Tree node = (Tree) malloc(sizeof(struct TreeNode));
        node->data = data; node->flag = 0;
        node->left = NULL; node->right = NULL;
        return node;
    }
    
    Tree insert(Tree root, int data) {
        if (!root) {
            root = newNode(data);
        } else if (data > root->data) {
            root->right = insert(root->right, data);
        } else if (data < root->data) {
            root->left = insert(root->left, data);
        }
        return root;
    }
    
    int judge(Tree root, int n) {
        int data, flag = 0;
        scanf("%d", &data);
        if (root->data != data) flag = 1;
        else root->flag = 1;
        for (int i = 1; i < n; i++) {
            scanf("%d", &data);
            if (!flag && !check(root, data)) flag = 1;
        }
        if (flag) return 0;
        else return 1;
    }
    
    int check(Tree root, int data) {
        if (root->flag) {
            if (data > root->data) {
                return check(root->right, data);
            } else if (data < root->data) {
                return check(root->left, data);
            } else {
                return 0;
            }
        } else {
            if (data == root->data) {
                root->flag = 1;
                return 1;
            } else {
                return 0;
            }
        }
    }
    
    void reset(Tree root) {
        if (root->left) reset(root->left);
        if (root->right) reset(root->right);
        root->flag = 0;
    }
    
    void freeTree(Tree root) {
        if (root->left) freeTree(root->left);
        if (root->right) freeTree(root->right);
        free(root);
    }
    
  • 相关阅读:
    字符串与指针{学习笔记}
    selenium 测试脚本
    多维数组与指针{笔记}
    SQL注入常用语句{笔记}
    C语言指针{学习笔记}
    字符编码
    移动窗体
    TreeView树形结构
    未能找到元数据文件解决办法
    gridview分页的问题
  • 原文地址:https://www.cnblogs.com/AndyHY-Notes/p/12546832.html
Copyright © 2020-2023  润新知