8.1 二叉排序树 —— C语言实现

系列文章目录

参考船说系列——数据结构与算法中的第八章内容。

  1. 二叉排序树
  2. AVL树
  3. 红黑树
  4. B-树


前言

数据结构 = 结构定义 + 结构操作
结构操作是用来维护结构性质的


一、二叉排序树基础

在这里插入图片描述二叉排序树(Binary Search Tree,BST)是一种二叉树,它具有以下性质:

  1. 每个节点都有一个值,且节点的值都不相同。
  2. 左子树中所有节点的值都小于该节点的值。
  3. 右子树中所有节点的值都大于该节点的值。
  4. 左右子树也分别为二叉排序树。

这些性质保证了二叉排序树的中序遍历是一个有序的序列。由于有序性,二叉排序树常被用于实现动态集合的数据结构,支持快速的查找、插入和删除操作。然而,如果插入的节点顺序不合理,可能导致二叉排序树退化成链表,影响其性能。

对于二叉排序树,平均情况下,查找、插入和删除操作的时间复杂度为O(log n),其中n为树中节点的数量。但是,在最坏情况下,二叉排序树可能退化成一个高度为n的链表,导致这些操作的时间复杂度为O(n)。

中序遍历:
在这里插入图片描述


二、二叉排序树的操作

2.1 插入

  1. 从根节点开始,比较要插入的值与当前节点的值。
    在这里插入图片描述

  2. 如果要插入的值小于当前节点的值,并且当前节点的左子节点为空,则将新节点插入为当前节点的左子节点;如果不为空,则继续向左子树遍历。(递归子问题)
    在这里插入图片描述

  3. 如果要插入的值大于当前节点的值,并且当前节点的右子节点为空,则将新节点插入为当前节点的右子节点;如果不为空,则继续向右子树遍历。(递归子问题)
    在这里插入图片描述

  4. 重复步骤2和步骤3,直到找到合适的位置插入新节点。
    在这里插入图片描述

2.2 删除

删除节点有几种情况要讨论:

  1. 删除叶子节点
    直接删除即可

  2. 删除出度为1的节点
    将其唯一子节点提升到要删除节点的位置

  3. 删除出度为2的节点
    在这里插入图片描述a. 20节点的前驱(前驱位置的出度只能是0或者1,因为前驱是之前节点中值最大的节点)替换20这个当前节点,这样20就成了它之前节点所在位置中的左子树中最大值的节点。这样删掉20节点就变成了一个删除出度为0或者1的问题了,解决办法就能参考前两种办法!!!
    b. 20节点的后继(后继位置的出度只能是0或者1,因为后继是之前节点中值最小的节点)替换20这个当前节点,这样20就成了它之前节点所在位置中的右子树中最小值的节点。这样删掉20节点就变成了一个删除出度为0或者1的问题了,解决办法就能参考前两种办法!!!

    有个容易找到前驱后继的方法:

    • 前驱是该节点的左子树一直往右,直到右节点为空的节点
    • 后继是该节点的右子树一直往左,直到左节点为空的节点

简单来说就是删除出度为2的节点,则可以选择将其右子树中最小的节点(后继)或左子树中最大的节点(前驱)替代要删除的节点,然后删除该最小或最大节点(变成了删除出度为0或者1的问题)。


三、代码演示

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define KEY(n) (n ? n->key : -1)

typedef struct Node{
   
   
	int key;
	struct Node *lchild, *rchild;
} Node;

Node *getNewNode(int key)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值