简述二叉搜索树
二叉搜索树又称二叉排序树,它或者是一棵空树
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树
searchTree.h
typedef char SearchType;
typedef struct SearchNode {
SearchType key; // 关键码
struct SearchNode* lchild;
struct SearchNode* rchild;
}SearchNode;
void SearchInit( SearchNode** root); //二叉搜索树的初始化
void SearchInsert( SearchNode** root, SearchType key); //往二叉搜索树中插入元素
SearchNode* SearchFind(SearchNode* root, SearchType to_find); //在二叉搜索树中查找元素
void SearchRemove( SearchNode** root, SearchType key); //在二叉搜索树中删除指定元素
searchTree.c
#include"searchTree.h"
#include<stdio.h>
#include<stdlib.h>
void SearchInit(SearchNode** root){
if(root==NULL){
return;
}
*root=NULL;
return;
}
SearchNode* CreatSearchNode(SearchType key){
SearchNode* new_node=(SearchNode*)malloc(sizeof(SearchNode));
new_node->key=key;
new_node->lchild=NULL;
new_node->rchild=NULL;
return new_node;
}
void SearchInsert(SearchNode** root, SearchType key){
if(root==NULL){
return;
}
if(*root==NULL){
SearchNode* new_node=CreatSearchNode(key);
*root=new_node;
return;
}
SearchNode* cur=*root;
if(key>cur->key){
SearchInsert(&cur->rchild,key);
}else if(key<cur->key){
SearchInsert(&cur->lchild,key);
}else{
//这里约定,不允许出现重复的数据
return;
}
return;
}
SearchNode* SearchFindByLoop(SearchNode* root,SearchType to_find){
if(root==NULL){
return NULL;
}
SearchNode* cur=root;
if(to_find<cur->key){
SearchFind(cur->lchild,to_find);
}else if(to_find>cur->key){
SearchFind(cur->rchild,to_find);
}else{
return cur;
}
}
SearchNode* SearchFind(SearchNode* root,SearchType to_find){
if(root==NULL){
return NULL;
}
SearchNode* cur=root;
while(cur!=NULL){
if(to_find<cur->key){
cur=cur->lchild;
}else if(to_find>cur->key){
cur=cur->rchild;
}else{
return cur;
}
}
}
void SearchRemove( SearchNode** root, SearchType key){
if(root==NULL){
return;
}
if(*root==NULL){
return;
}
SearchNode* to_remove=*root;
SearchNode* parent=NULL;
//先找到要删除的节点
while(to_remove!=NULL){
if(key<to_remove->key){
parent=to_remove;
to_remove=to_remove->lchild;
}else if(key>to_remove->key){
parent=to_remove;
to_remove=to_remove->rchild;
}else{
break; //找到就直接跳出循环
}
}
if(to_remove==NULL){
printf("没找到节点\n");
}
//找到节点后分四种情况讨论
//要删除的节点没有左右子树,直接删除
if(to_remove->lchild==NULL&&to_remove->rchild==NULL){
if(to_remove==*root){
*root==NULL;
}
if(parent->lchild==to_remove){
parent->lchild=NULL;
}else{
parent->rchild=NULL;
}
free(to_remove);
return;
//要删除的节点有左子树,没有右子树,直接把左子树挂在要删除节点的父节点的孩子节点上
}else if(to_remove->lchild!=NULL&&to_remove->rchild==NULL){
if(to_remove==*root){
*root=to_remove->lchild;
}else{
if(parent->lchild==to_remove){
parent->lchild=to_remove->lchild;
}else{
parent->rchild=to_remove->lchild;
}
}
free(to_remove);
return;
//要删除的节点没有左子树,有右子树,直接把要删除节点的右子树挂在要删除节点的父节点的孩子节点上
}else if(to_remove->lchild==NULL&&to_remove->rchild!=NULL){
if(to_remove==*root) {
*root=to_remove->rchild;
}else{
if(parent->lchild==to_remove){
parent->lchild=to_remove->rchild;
}else{
parent->rchild=to_remove->rchild;
}
}
free(to_remove);
return;
}else{
//要删除的节点有左右子树,找到删除节点右子树的最小值,赋值给删除节点,删除最小值节点
SearchNode* min=to_remove->rchild;
SearchNode* min_parent=to_remove;
while(min->lchild!=NULL){
min_parent=min;
min=min->lchild;
}
to_remove->key=min->key;
if(min_parent->lchild==min){
min_parent->lchild=min->rchild;
}else{
min_parent->rchild=min->rchild;
}
free(min);
return;
}
}
测试代码///
#define PrintHeader printf("\n===============%s==============\n",__FUNCTION__)
void TestInit(){
PrintHeader;
SearchNode* root;
SearchInit(&root);
printf("tree expect NULL,actual %p\n",root);
}
void searchPreOrder(SearchNode* root){
if(root==NULL){
return;
}
printf("%c ",root->key);
searchPreOrder(root->lchild);
searchPreOrder(root->rchild);
return;
}
void searchInOrder(SearchNode* root){
if(root==NULL){
return;
}
searchInOrder(root->lchild);
printf("%c ",root->key);
searchInOrder(root->rchild);
return;
}
void TestInsert(){
PrintHeader;
SearchNode* root;
SearchInit(&root);
SearchInsert(&root,'a');
SearchInsert(&root,'c');
SearchInsert(&root,'f');
SearchInsert(&root,'b');
SearchInsert(&root,'e');
printf("preOreder:\n");
searchPreOrder(root);
printf("\n");
printf("preOreder:\n");
searchInOrder(root);
}
}
void TestFind(){
PrintHeader;
SearchNode* root;
SearchInit(&root);
SearchInsert(&root,'a');
SearchInsert(&root,'c');
SearchInsert(&root,'f');
SearchInsert(&root,'b');
SearchInsert(&root,'e');
SearchNode* ret=SearchFindByLoop(root,'f');
SearchNode* ret2=SearchFind(root,'b');
printf("ecpectel f,actual %c",ret->key);
printf("ecpectel b,actual %c",ret2->key);
}
void TestRemove(){
PrintHeader;
SearchNode* root;
SearchInit(&root);
SearchInsert(&root,'a');
SearchInsert(&root,'c');
SearchInsert(&root,'f');
SearchInsert(&root,'b');
SearchInsert(&root,'e');
SearchRemove(&root,'b');
searchPreOrder(root);
printf("\n");
searchInOrder(root);
}
int main(){
TestInit();
TestInsert();
TestFind();
TestRemove();
return 0;
}