二叉树--是否是二叉搜索树

二叉搜索树(Binary Search Tree)
  • 二叉树搜索树
  • 二叉搜索树是基于二分算法分解问题的灵感所研发的一棵树
  • 特点
  • 根节点比左子树所有结点要大或者等于
  • (root->left).data <= root->data
  • 根节点比右子树所有结点
  • (root->right0.data > root->data
递归实现代码
#include<stdio.h>
#include<stdlib.h>
//The code to work that
// if The root is a Binary Search Tree and printf("yes") or no
typedef struct BstNode{
    int Data;
    struct BstNode *Left;
    struct BstNode *Right;
}BstNode;
void PreOder(BstNode* root);
BstNode* GetNode(int item);
BstNode* Insert(BstNode* root,int data);
int IsBinarySearchTree( BstNode* root);
int IsSubtreeLesser(BstNode* root, int value);
int IsSubtreeGreater(BstNode* root, int value);
BstNode* CreatTree();

int main()
{
    BstNode* T = CreatTree();  //普通二叉树 不是二进制搜索树
    // int x=  1;;
    // while(x)
    // {
    //     scanf("%d", &x);
    //     T = Insert(T,x);
    // }
    PreOder(T);
    printf("\n");
   if( !IsBinarySearchTree(T))  //取反
        printf("No\n");
    
    return 0;
}

BstNode* GetNode(int item)
{
    BstNode* node = (BstNode*) malloc(sizeof(BstNode));  //申请结点
    node->Data = item;
    node->Left = node->Right = NULL;
    return node;
}

BstNode* Insert(BstNode* root,int data)  //给定一个树的根节点
{
        if(root == NULL){
           root = GetNode(data);
        }else if(data <= root->Data )
        {
            root->Left =Insert(root->Left,data); //函数Insert返回类型是个指针我们要让某个变量去接收这个指针
        }else if( data > root->Data)
        {
            root->Right = Insert(root->Right,data);
        }
        return root;
}

BstNode* CreatTree()
{
     BstNode* root = NULL;
        int ch;
        scanf("%d",&ch); //

        if( ch!= 0)
        {
            root = (BstNode*)malloc(sizeof(BstNode));
            root->Data = ch;

            root->Left = CreatTree();
            root->Right = CreatTree();
        }else{
            root = NULL;
        }
        return root; //返回根节点
    // BstNode* root = NULL;
    //     int ch;
    //     scanf("%d", &ch);
    //     if( ch == 0)
    //     {
    //         return NULL;
    //     }else{
    //          root = (BstNode*) malloc(sizeof(BstNode)); //申请结点
    //         root->Data = ch;
    //         root->Left = root->Right = NULL; 
    //         root->Left = CreatTree();
    //        root->Right = CreatTree();
    //         return root;
    //     }
}

void PreOder(BstNode* root)
{
    if(root == NULL) return;
    else{
        printf("%5d", root->Data);
        PreOder(root->Left);
        PreOder(root->Right);
    }
}

int IsBinarySearchTree( BstNode* root)
{
  if( root == NULL) return 1; //当结点为空无法判断 所以不改变函数的状态

    if(IsSubtreeLesser(root->Left,root->Data)  //用当前根节点的data  去和左子树所有结点比较
        && IsSubtreeGreater(root->Right, root->Data) //用当前根节点的data 去和右子树的所有结点比较大小
        && IsBinarySearchTree(root->Left)    //递归调用自己 将根的左子树作为一颗二叉树 继续求解
        && IsBinarySearchTree(root->Right))  //同上
    return 1;   //四个条件达成 那么这棵树是二叉树
    else 
        return 0;
}

int IsSubtreeLesser(BstNode* root, int value)
{
    if( root == NULL) return 1;

    if( root->Data <= value   //当前子树的根 应该比他的父节点的data要小
        && IsSubtreeLesser( root->Left,value)  //同理 当前子树的根要比 子树的根的子树要大
        && IsSubtreeLesser( root->Right, value) ) 
        return 1;
    else 
         return 0;
}
int IsSubtreeGreater(BstNode* root, int value)
{
        if (  root == NULL ) return 1;

        if( root->Data > value
            && IsSubtreeGreater(root->Left, value)
            && IsSubtreeGreater( root->Right, value))    
            return 1;
        else 
            return 0;
        
        
}
解题思路

递归求解是否是二叉树,
递归求解问题本质上是将大问题划分成不同的子问题 最后逐一解决

在这里插入图片描述

如图
在这里插入图片描述
最外面看 是根节点 左子树 右子树

把根节点的左子树单独拿出来看 还是一颗二叉树

我们简单的把问题分为三个步骤
1.引入 根节点 拿到根节点的data
2. 用根结点去比较左子树 左子树一定等于或小于根节点
3. 用根节点去比较右子树 右子树一定大于根节点的data

此时我们发现 左子树和右子树又可以单独的拿出来做操作

所以我们就自上而下的去求左右子树的大小问题
一层一层的往下走

遇到空节点 就什么都不做 返回1
遇到不匹配就返回0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值