二叉搜索树,顾名思义,主要作用为搜索,确定该树中是否存在要搜索的数据。基于找到该数据衍生除了对搜索二叉树的一系列操作,比如插入新数据,删除旧数据等等。
搜索二叉树的性质(设节点为Root)
1)root的左孩子的值永远小于root的值
2)root的右孩子的值永远大于root的值
3)root的左右子树依旧遵循此性质
特点:搜索二叉树不允许一棵树中出现两个相同的数据,(个人看来,为了减少误差,如果出现两个相同的数据,则会有两个地址,大家可以自行思考一下,如果出现这种情况会有什么后果!)
搜索二叉树的创建(也可以称为插入,详细请参考上一篇博客https://blog.csdn.net/xinger_28/article/details/82941358)
此博客主要讨论搜索二叉树的查找和删除
查找key:(步骤)
1)如果根节点不空:
如果根节点Key==查找key,返回key所在节点位置。
如果根节点Key>查找Key,则在其左子树中找
如果根节点Key<查找key,则在其右子树中找
2)如果根节点为空,返回NULL
删除key:(步骤)
首先查找元素是否在搜索二叉树中,如果不存在,则返回,否则可以分四种情况删除Key。(已找到root->key==key,root的双亲节点为parent)
1)要判断root为双亲节点的左右孩子,如果为左孩子:
节点无左孩子,双亲节点的左孩子指向root的右孩子(此时,无需探讨root的右孩子是否为空,若为空,叶子结点)
节点无右孩子,双亲节点的左孩子指向root的左孩子。
如果右孩子
节点无左孩子,双亲节点的右孩子指向root的右孩子(此时,无需探讨root的右孩子是否为空,若为空,叶子结点)
节点无右孩子,双亲节点的右孩子指向root的左孩子。
头文件:二叉搜索树.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
typedef int Key;
typedef struct BSTserchtree{
Key key;
struct BSTserchtree*left;
struct BSTserchtree*right;
}BST;
//创建二叉树,也称为插入
int CreatTree(BST**tree, Key key)
{
BST*root = *tree; //保存根节点
BST*parent = NULL;//使双亲节点指向空
while (root!=NULL)
{
if (root->key == key)//搜索二叉树中已经存在key值
{
printf("已经存在\n");
return -1;
}
parent = root;//表明root不为空,则存在双亲节点,使parent指向root的双亲节点.
if (root->key > key)
root = root->left;//root的值大于key,则key的节点应该存在于root的左子树。
else
root = root->right;//root的值小于key,则key的节点应该存在于root的右子树。
}
//将值为Key的建立新节点--------插入!
BST*node = (BST*)malloc(sizeof(BST));
node->key = key;
node->left = node->right = NULL;
//判断根节点是否为空,若为空,将node节点直接付给*tree,使之成为根节点。
if (parent == NULL)
{
*tree = node; //此处注意!!!要用*tree保存node的信息,否则在调用堆栈结束后,无根节点。
return 0; //原因在于root为临时变量,此函数一用完将会被销毁,tree中的信息也将会改变
}
if (parent->key > key) //找到双亲节点,判断双亲节点值与Key值得大小,确定node应该存在的位置
parent->left = node;
else
parent->right = node;
return 0;
}
//查找
BST* LOOK(BST*root,Key key)
{
//BST*root = *tree;
BST*parent = NULL;
//查找Key值所在的位置Root,并且找到双亲节点的位置。
while (root != NULL&&root->key != key)
{//root不为空,则parent也不为空
parent = root;
if (root->key > key)
root = root->left;
else
root = root->right;
}
//parent为NULL或者root 为空。根本就不存在节点或者未找到该节点。删除肯定出错!
if (parent == NULL || root == NULL)
{
printf("没找到!\n");
return NULL;
}
return root;
}
//删除
int Delete(BST**tree, Key key)
{
BST*root = *tree;
BST*parent = NULL;
//查找Key值所在的位置Root,并且找到双亲节点的位置。
while (root != NULL&&root->key != key)
{//root不为空,则parent也不为空
parent = root;
if (root->key > key)
root = root->left;
else
root = root->right;
}
//parent为NULL或者root 为空。根本就不存在节点或者未找到该节点。删除肯定出错!
if (parent == NULL || root == NULL)
{
printf("没找到!\n");
return -1;
}
//走到这里,表明root不为空,找到该节点。
if (parent->left == root){
if (root->left == NULL)//该节点的左孩子为空,使双亲节点的左孩子指向Root的右孩子
parent->left = root->right;
else
parent->left = root->left;
}
else{
if (root->left == NULL)//该节点的左孩子为空,使双亲节点的右孩子指向Root的右孩子
parent->right = root->right;
else
parent->right = root->left;
}
return 0;
}
void test()
{
BST*tree = NULL;
CreatTree(&tree, 5);
CreatTree(&tree, 4);
CreatTree(&tree, 3);
CreatTree(&tree, 8);
CreatTree(&tree, 6);
CreatTree(&tree, 10);
CreatTree(&tree, 7);
BST*pp=LOOK(tree, 7);
Delete(&tree, 10);
Delete(&tree, 11);
}
源文件:test.cpp
#include"二叉搜索树.h"
int main()
{
test();
system("pause");
return 0;
}