数据结构与算法8の查找の搜索二叉树


浙江大学数据结构与算法

1. 查找算法

1. 通用查找算法


/* 二叉搜索树数据结构 */
typedef struct BiNode
{
	ElemType data;
	struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

/*  尾递归的实现方式  */
Position Find(ElemType key, BiTree BST)
{
	if(BST==NULL)
		return NULL;
	if(key < BST->data)
	{
		return Find(key, BST->lchild);
	}
	else if(key > BST->data)
	{
		return Find(key, BST->rchild);
	}
	else
		return BST;
}

/*  循环迭代的实现方式  */
Position Find(ElemType key, BiTree BST)
{
	while(BST)
	{
		if(key < BST->data)
			BST=BST->lchild;
		else if(key > BST->rchild)
			BST=BST->rchild;
		else
			return BST;
	}
	return NULL;
}
//此时查找效率决定于树的高度

2. 最大/最小元素查找算法

/* 循环迭代查找最大元素 */
Position FindMax(BiTree BST)
{
	if(BST)
		while(BST->rchild)	BST=BST->rchild;
	return BST;
}
/* 递归实现查找最小元素 */
Position FindMin(BiTree BST)
{
	if(!BST) return NULL;
	else if(!BST->lchild)	//此时已经达到最左边叶子结点
		return BST;
	else
		return FindMin(BST->lchild);
}

2. 插入

BiTree Insert(ElemType key, BiTree BST)
{
	if(!BST)
	{
		BST = (BiTree)malloc(sizeof(BiNode));
		BST->data = key;
		BST->lchild = BST->rchild = NULL;
	}
	else
	{
		if(key > BST->data)
			return Insert(key, BST->lchild)
		else
			return Insert(key, BST->rchild);
	}
	return BST;
}  

程序递归调用分析:
假设要插入的元素是35,要插入的树是:
在这里插入图片描述
程序执行过程中,经历了:
三次递归调用:寻找合适的插入/挂载点;
三次递归返回:依次完成结点的挂载;

程序开始运行:
在这里插入图片描述
第一次递归调用:

在这里插入图片描述
第二次递归调用:
在这里插入图片描述
第三次调用:
在这里插入图片描述
第一次递归返回:
在这里插入图片描述
第二次返回调用:
在这里插入图片描述
第三次返回调用:
在这里插入图片描述


至此,所有的递归均完成,得到的BST指向根节点,此时的二叉搜索树已经是插入元素之后的。

3. 删除

二叉搜索树的删除有三种情况:

  1. 待删除结点是叶节点:直接删除,将其父节点指针置空
  2. 待删除结点仅有一个孩子结点:将其父节点的指针指向要删除结点的孩子结点
  3. 待删除结点有左右两颗子树:用另一结点替代被删除结点,左子树最大结点或者右子树最小结点。这样做其实就是把这种情况转化为第二种情况,在代码里更能体现出这一思想,具体如下:
    (用右子树最小元素替代)
    在这里插入图片描述
    (用左子树最大元素替代)
    在这里插入图片描述
    在这里插入图片描述
    <补充>:
    左子树的最大元素一定没有右子树;
    右子树的最小元素一定没有左子树;

Codes:

BiTree Delete(ElemType key, BiTree BST)
{
	Position Tmp;
	if(!BSP) printf("要删除的元素为找到!\n");
	else if(key < BST->data)
		BST->lchild = Delete(key, BST->lchild);
	else if(key > BST->data)
		BST->rchild = Delete(key, BST->rchild);
	else		//找到要删除的结点
		if(BST->lchild && BST->rchild)
		{
			Tmp=FindMin(BST->rchild);
			BST->data=Tmp->data;
			BST->rchild=Delete(BST->data, BST->rchild);
		}else {
			Tmp=BST;
			if(!BST->lchild)
				BST = BST->rchild;
			else if(!BST->rchild)
				BST = BST->lchild;
			free(Tmp);
		}
	return BST;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值