二叉搜索树(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