• 【数据结构】18 二叉搜索树(查找,插入,删除)


    定义

    二叉搜索树也叫二叉排序树或者二叉查找树。它是一种对排序和查找都很有用的特殊二叉树。
    一个二叉搜索树可以为空,如果它不为空,它将满足以下性质:

    1. 非空左子树的所有键值小于其根节点的键值
    2. 非空右子树的所有键值都大于其根结点的键值
    3. 左、右子树都是二叉树

    动态查找

    查找操作Find

    在二叉搜索树中查找关键字为X的结点,返回其所在结点的地址。查找过程如下:

    1. 查找从树的根节点开始,若树为空,返回NULL
    2. 搜索树非空,则根节点关键字和X比较,依据结果,需要进行不同的处理
      若根节点键值小于X,在根节点右子树中查找
      若根节点的键值大于X,在根节点的左子树中查找
      若两者比较结果相等,搜索完成。

    递归代码

    Position Find_RE(BinTree BT, ElementType X) {
    	if (!BT) {
    		return NULL;
    	}
    	if (X > BT->Data) {
    		return Find_RE(BT->Right, X);
    	}
    	else if(X < BT->Data)
    	{
    		return Find_RE(BT->Left, X);
    	}
    	else
    	{
    		return BT;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    迭代函数

    Position Find_D(BinTree BT, ElementType X) {
    	BinTree T = BT;
    	while (T) {
    		if (T->Data > X) {
    			T = T->Left;
    		}
    		else if (T->Data < X) {
    			T = T->Right;
    		}
    		else
    		{
    			return T;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    查找最大和最小元素

    根据二叉搜索树的性质,最大元素一定在最右分支的尾端,最小元素一定在最左分支的尾端。
    递归函数

    Position FindMin(BinTree BT) {
    	if (!BT) {
    		return NULL;
    	}
    	else if(!BT->Left)
    	{
    		return BT;
    	}
    	else
    	{
    		return FindMin(BT->Left);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    迭代函数

    Position FindMinD(BinTree BT) {
    	BinTree T = BT;
    	while (T->Left) {
    		T = T->Left;
    	}
    	return T;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    找最大值只需要把left换成right

    插入

    BinTree Insert(BinTree BT, ElementType X) {
    	if (!BT) {
    		BT = (BinTree)malloc(sizeof(struct TNode));
    		BT->Data = X;
    		BT->Left = BT->Right = NULL;
    	}
    	else {
    		if (X > BT->Data) {
    			BT->Right =  Insert(BT->Right, X);
    		}
    		else if (X < BT->Data) {
    			BT->Left =  Insert(BT->Left, X);
    		}
    		
    	}
    	return BT;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    删除

    二叉搜索树的删除比较复杂,需要考虑节点的位置

    1. 叶结点
      可以直接删除,将其父节点指针置空即可。
    2. 只有一个孩子结点
      要修改其父节点的指针,指向要删除结点的孩子结点。
    3. 有左、右两颗树
      究竟用哪颗子树的根结点来填充删除节点的位置?有两种选择方式:选择左子树的最大元素,或者选择右子树的最小元素。无论哪种方式,最后被选择的结点必定最多只有一个孩子。
      在这里插入图片描述

    采用右子树的最小元素的删除代替策略。
    代码思路: 先找到要删除元素的位置,若其具有左右子树,找到该位置的右子树里面的最小元素,赋值到该位置上,在其右子树中删除最小元素(递归调用),若只有一个子树或者没有,易操作。

    
    BinTree DeleteBT(BinTree BT, ElementType X) {
    	Position p;
    	if (!BT) {
    		printf("can't find the node\n");
    	}
    	else {
    		if (X > BT->Data) {
    			BT->Right = DeleteBT(BT->Right, X);
    		}
    		else if (X < BT->Data) {
    			BT->Left = DeleteBT(BT->Left, X);
    		}
    		else {
    			if (BT->Left && BT->Right) {
    				//FIND THE Min OF Right TREE
    				p = FindMin(BT->Right);
    				BT->Data = p->Data;
    				BT->Right = DeleteBT(BT->Right, p->Data);
    			}
    			else {
    				p = BT;
    				if (!BT->Left) {
    					BT = BT->Right;
    				}
    				else { BT = BT->Left; }
    				free(p);
    			}
    		}
    	}
    	return BT;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  • 相关阅读:
    【组成原理-IO系统】IO控制方式
    Docker命令
    dubbo-admin 2.7.2安装记录
    【计算机毕业设计】Java ssm 高校运动会管理系统(开题+源码+论文)
    中秋味的可视化大屏 【以python pyecharts为工具】
    关于二叉树的算法(JavaScript)
    数学建模竞赛全面指南:华为杯国赛数学建模
    ShareSDK Android端主流平台分享示例
    k8s学习-Secret(创建、使用、更新、删除等)
    【回归预测-LSSVM预测】基于PSO和PSR结合LSSVM实现数据回归预测附matlab代码
  • 原文地址:https://blog.csdn.net/vox520/article/details/136141138