C语言实现二叉排序树的增删查操作

这篇博客介绍了如何使用C语言实现二叉排序树的基本操作,包括创建、插入节点、删除节点和查找节点。通过示例代码展示了如何构建、输出、删除和搜索树中的元素,并提供了完整的main函数来演示这些操作。
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode{
    struct TreeNode* lchild;
    struct TreeNode* rchild;
    int val;

}TreeNode;

//构造树节点
TreeNode* createTreeNode(int val){
    TreeNode *node;
    node = (TreeNode*)malloc(sizeof(TreeNode));
    node->val = val;
    node->lchild = NULL;
    node->rchild = NULL;
    return node;
}

//创建树
TreeNode* createTree(int *array,int length){
  TreeNode *root = createTreeNode(array[0]);
  TreeNode *temp = root;
  TreeNode *parent = root;
  int i = 1;
  while(i<length){
        temp = root;
    while(temp){
            parent = temp;
        if(temp->val>array[i]){
            temp = temp->lchild;
        }
        else if(temp->val<array[i]){
             temp = temp->rchild;

        }
        else{
            break;

        }

    }

    if(parent->val>array[i])
        parent->lchild=createTreeNode(array[i]);
    else
        parent->rchild=createTreeNode(array[i]);




    i++;
  }
  return root;


}
//递归寻找删除节点的位置
void del(TreeNode *node,int key,TreeNode *parent){
    if(node==NULL)
        return;
    if(key==node->val){
        deleteNode(node,parent);
    }
    else if(key>node->val){
        del(node->rchild,key,node);
    }else{

        del(node->lchild,key,node);
    }


}

//删除节点的核心方法
void deleteNode(TreeNode *node,TreeNode *parent){
    int flag = -1;
    if(parent->lchild==node){

            flag=1;
    }else{

            flag=0;
    }
    if(node->lchild==NULL&&node->rchild==NULL){
        if(flag==1){
            parent->lchild = NULL;
        }else{
            parent->rchild = NULL;

        }

    }
    else if(node->lchild!=NULL&&node->rchild==NULL){//删除节点有左子树
            //重接左子树
            if(flag==1){
                parent->lchild = node->lchild;
            }else{
                 parent->rchild = node->lchild;

            }

    }
    else if(node->rchild!=NULL&&node->lchild==NULL){//删除节点有右子树
            //重接右子树
            if(flag==1){
                parent->lchild = node->rchild;
            }else{
                 parent->rchild = node->rchild;

            }

    }else{

        //左右子树都不空

        //右子树取最小的拿过来替代删除节点 或者将删除节点左子树上最大的替代 因为左子树最大的和右子树最小的都一定是叶子节点
        //替代之后,既能保持排序二叉树的特性,移除叶子节点也很轻松

        TreeNode *pre = node;
        TreeNode *in = node->rchild;//往右一步
        while(in->lchild){//向左搜索 找到最左边的

            pre = in;//保存前缀节点
            in = in->lchild;

        }
        //替补
        node->val = in->val;
        if(pre==node)//判断删除节点右子树是否只有一个节点
            pre->rchild = NULL;
        else//如果不是 则删除pre的左子树
            pre->lchild = NULL;




    }



}
//先序输出
void output(TreeNode *root){
    if(root==NULL)
        return;
    printf("%d  ",root->val);
    output(root->lchild);
    output(root->rchild);
}

//查找节点

TreeNode* searchTree(TreeNode *root,int key){
    if(root==NULL){
        return NULL;
    }

    if(root->val==key){
        return root;
    }

    root->val>key?searchTree(root->lchild,key):searchTree(root->rchild,key);//向左或向右查找

}

//插入节点
TreeNode* insertNode(int value,TreeNode *root){
    if(root==NULL){
        TreeNode *node = createTreeNode(value);
        return node;

    }

    if(root->val == value){//如果相等 则直接返回
        return root;
    }
    if(root->val>value){
        //向左遍历

        root->lchild = insertNode(value,root->lchild);
    }else{
	//向右遍历
        root->rchild = insertNode(value,root->rchild);
    }


    return root;


}

int main()
{

    int a[7]={10,5,17,20,6,15,18};
    TreeNode *root = createTree(a,7);
    root = insertNode(17,root);//插入
    output(root);
    del(root,10,root);//删除
    output(root);

    //查找
    TreeNode *node = searchTree(root,20);
    output(node);

    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值