C语言实现二叉搜索树的基本操作

简述二叉搜索树

二叉搜索树又称二叉排序树,它或者是一棵空树

若它的左子树不为空,则左子树上所有节点的值都小于根节点的值

若它的右子树不为空,则右子树上所有节点的值都大于根节点的值

它的左右子树也分别为二叉搜索树

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;
}             

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值