相同二叉搜索树的判定

//两个序列是否对应相同搜索树的判别
//1.分别建两棵搜索树的判别方法
//2.不建树的判别方法
//3. 建一棵树,再判别其他序列是否与该树一致


#include <stdio.h>
#include <stdlib.h>
typedef int Status;  //函数类型
typedef int ElementType;
#define true 1;
#define false 0;
typedef int bool;  
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, int N);
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\n");
            }
            else
            {
                printf("No\n");
            }
            ResetT(T);
        }
        FreeT(T);
        scanf("%d", &N);
    }
}
在C语言中,判断一棵树是否为二叉搜索树(Binary Search Tree,BST),我们可以采用中序遍历的方式来实现。二叉搜索树的特点是:对于任意一个节点,其左边的所有节点值均小于该节点值,而右边的所有节点值均大于该节点值。因此,如果我们能保证在中序遍历的过程中节点的值是单调递增的,则说明这棵树是一个有效的二叉搜索树。 下面是如何使用C语言编写一个函数来检查一个给定的二叉搜索树: ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* left; struct Node* right; } Node; Node* newNode(int item) { Node* temp = (Node*)malloc(sizeof(Node)); temp->data = item; temp->left = NULL; temp->right = NULL; return temp; } int checkBSTUtil(Node* node, int lower, int upper); bool checkBST(Node* root) { return checkBSTUtil(root, INT_MIN, INT_MAX); } int checkBSTUtil(Node* node, int lower, int upper) { if (node == NULL) { return 1; // 空树视为有效BST } if (node->data <= lower || node->data >= upper) { return 0; // 如果当前节点值超出限制范围则不是BST } // 检查左子树是否存在违反BST规则的节点 if (!checkBSTUtil(node->left, lower, node->data)) { return 0; } // 检查右子树是否存在违反BST规则的节点 if (!checkBSTUtil(node->right, node->data, upper)) { return 0; } return 1; // 若以上条件皆满足,则此节点及其子节点构成有效BST } void main() { Node *root = newNode(5); root->left = newNode(3); root->right = newNode(7); root->left->left = newNode(2); root->left->right = newNode(4); root->right->left = newNode(6); root->right->right = newNode(8); printf("%s\n", checkBST(root)? "树是二叉搜索树" : "树不是二叉搜索树"); } ``` 在这个程序中,`checkBST()` 函数用于启动中序遍历过程并通过递归调用 `checkBSTUtil()` 函数检查树的合法性。`checkBSTUtil()` 函数接受当前节点和允许的最大最小值作为参数,如果当前节点的值不在这个范围内,则返回 false,表示这不是一个有效的BST。 最后的 `main()` 函数创建了一个简单的二叉搜索树并测试了我们的检查函数,打印出结果表明树是否为合法的二叉搜索树。 --- ### 相关问题: 1. **如何在 C++ 或 Java 中实现类似的功能?** 可以参考 C 语言版本的实现思路,在相应的语法基础上调整代码结构和关键字即可。 2. **如果二叉搜索树包含重复值,这个算法仍然适用吗?** 如果二叉搜索树允许有相同的值,那么基于值递增的判断可能不再完全准确,因为同值的节点可能会破坏递增的顺序。此时应考虑修改判断逻辑以适应这一情况。 3. **如何利用深度优先搜索(DFS)而非中序遍历来判断二叉搜索树?** 可以通过前序遍历或后序遍历的方式,递归地检查左右子树的大小关系,以此来判断整棵二叉搜索树的有效性。每层递归中都需要检查当前节点与其父节点的关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值