基础练习 创建二叉搜索树并实现查找和删除功能(C语言)

1. 需要掌握的知识

二叉搜索树的基本特性

2. 代码框架(重点)

2.1 采用的数据结构

结构体数组

typedef int ElementType; //通过typedef增加灵活性
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

2.2 各分支函数

  1. Insert()函数,用于建树,向树中插入一个树节点:分树空和树非空两种情况,递归调用即可,属于基本功
    21.10.8 疑问:插入时,不用考虑二叉搜索树被破坏的情况吗?比如说,持续插入越来越小的数,这种插入方式难道不会导致树向一边倾斜吗? 自己晕头了,文中要求的是BST Binary Search Tree 二插搜索树的插入,并不是AVL 平衡二叉树。AVL才要求:左右两个子树的高度差的绝对值不超过1,并且左右两个子树也是平衡二叉树
BinTree Insert( BinTree BST, ElementType X )
{
	if(!BST)
	{
		BST=(BinTree)malloc(sizeof(struct TNode));
		BST->Data=X;
		BST->Left=BST->Right=NULL;
	}
	else
	{
		if(X>BST->Data)
			BST->Right=Insert(BST->Right,X);	
		else if(X<BST->Data)
			BST->Left=Insert(BST->Left,X);		
	}
	return BST;
}
  1. 查找最大值 和 最小值 : BST 最左侧的结点为最小值,最右侧的结点为最大值。注意,别遗漏树为空的情况
Position FindMin( BinTree BST )
{
	if(!BST) return NULL;  //树为空时
	while(BST->Left)
		BST=BST->Left;
	return BST;
}

Position FindMax( BinTree BST )
{
	if(!BST) return NULL; 
	while(BST->Right)
		BST=BST->Right;
	return BST;
}
  1. Find( ) 查找函数:根据BST左小右大的特性实现即可,使用递归时,别遗漏返回条件
Position Find( BinTree BST, ElementType X )
{
	if(!BST) return NULL;
	if(X==BST->Data)
		return BST;
	else if(X>BST->Data)
		return Find(BST->Right,X);
	else
		return Find(BST->Left,X);
}

  1. Delete( ) 核心函数,挺锻炼人的逻辑思维能力。我开始一直受困于如何找到删除节点的父亲结点,最后发现不依赖父结点也能正常’删除’。
    4.1 首先需要明确,删除存在三种可能:(1)删除结点是叶结点 (2)删除结点有一个子树 (3)删除结点有两个子树
    4.2 对于(1)删除结点是叶结点,删除结点的父结点指向NULL即可;对于(2),父结点指向删除结点的子树即可;对于(3),稍微复杂些,根据BST特性,挑选左子树的最大值结点 或 右子树的最小值结点 替换删除结点,然后删除左子树或右子树上的替换结点
    4.3 不用找到删除结点的父结点,从删除结点自身入手
    4.4 别遗漏树空的情况

2021.10.8:全靠过去的自己为自己续命,总结的确实挺好的(手动咧嘴笑)

BinTree Delete( BinTree BST, ElementType X ) //core
{
	if(!BST) 
	{
		printf("Not Found\n");
		return NULL;
	 } 
	BinTree tmp;
	//通过if语句锁定查找的三种情况:大 小 相等
	if(X>BST->Data)	BST->Right=Delete(BST->Right,X);
	else if(X<BST->Data)	BST->Left=Delete(BST->Left,X);
	else //找到了,准备删除,分三种情况考虑
	{
		if(BST->Left && BST->Right) //删除结点存在两个子树
		{
			tmp=FindMin(BST->Right) ;
			BST->Data=tmp->Data; //替换掉结点值,而不用修改指针指向 
			BST->Right=Delete(BST->Right,tmp->Data); //将替换的结点删除即可 
		} 
		else
		{
			tmp=BST;
			if(!BST->Left) BST=BST->Right; //删除结点右子树为空或非空:此时也不用考虑删除结点的父结点,改变删除结点自身即可
			else if(!BST->Right) BST=BST->Left;//删除结点左子树为空或非空
			free(tmp);
		}
	}
	return BST;
}

3. 在线测试位置

参考信息

浙江大学 陈越、何钦铭老师主讲的数据结构

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值