(BST)二叉搜索树操作(二)

这篇博客接着上篇博客,主要讲二叉树搜索树的删除操作。


如上图,对一个二叉搜索树进行删除操作要分情况讨论。

   1.要删除的节点没有左右孩子,(如图中的0,或者9);

   2.要删除的节点有左孩子,没右孩子(如图中的1);

(1)要删除的节点是根节点;

(2)要删除的节点不是根节点;

   3.要删除的节点没有左孩子,有右孩子(如图中的8);

(1)要删除的节点是根节点;

(2)要删除的节点不是根节点;

    4.要删除的节点有左孩子,也有右孩子;

(图2)

         (1)要删除的节点是根节点

【1】在其右子树中寻找最小的节点temp,将temp的key和value赋给,要删除 的节点pro,删除temp;(如图2

~1.temp有右孩子。(需要其双亲节点pParent,将pParent的左孩子指向temp 的右孩子,然后free);

                ~2.temp没有右孩子。(直接【1】);


(2)要删除的节点不是根节点。

   【1】pro的右孩子temp有左孩子,没有右孩子(如图3);

(图3)

【2】pro的右孩子temp没有左孩子,有右孩子;(如图4)

(图4)

【3】pro的右孩子temp没有左孩子,没有右孩子;


代码如下:

bool Delete_node(pTreeNode proot, int key)
	{
		if(proot == NULL)
			return false;
		if(!find(key))
			return false;

		pTreeNode pro = proot;
		pTreeNode pParent = NULL;
		while(pro)
		{
			if (NULL != pro && pro->key == key)
			{
				break;
			}
			if (NULL != pro && pro->key < key)
			{
				pParent = pro;
				pro = pro->pright;
			}
			if (NULL != pro && pro->key > key)
			{
				pParent = pro;
				pro = pro->pleft;
			}
		}

		//第一种情况:没有孩子节点
		if (pro->pleft == NULL && pro->pright == NULL)
		{
			free(pro);
			pro = NULL;
			pParent->pleft = NULL;
			pParent->pright = NULL;
			return true;
		}

		//2.有左孩子,没有右孩子
		if (pro->pleft != NULL && pro->pright == NULL)
		{
			//如果根节点
			if (pro == proot)
			{
				pro->pleft = proot;
				free(pro);
				return true;
			}
			else
			{
				pParent->pleft = pro->pleft;
				free(pro);
				pro = NULL;
				return true;
			}
		}

		//没有左孩子,有右孩子
		if (pro->pleft == NULL && pro->pright != NULL)
		{
			//如果根节点
			if (pro == proot)
			{
				pro->pright = proot;
				free(pro);
				return true;
			}
			else
			{
				pParent->pright = pro->pright;
				free(pro);
				pro = NULL;
				return true;
			}
		}

		//有左孩子,也有右孩子
		if (pro->pleft != NULL && pro->pright != NULL)
		{
			pTreeNode temp = pro->pright;
			pTreeNode pp = NULL;
			if (temp->pleft == NULL && temp->pright != NULL)
			{
				pParent->pright = temp;
				temp->pleft = pro->pleft;
				free(pro);
				pro = NULL;
			}
			else if(temp->pleft == NULL && temp->pright == NULL)
			{
				pParent->pleft = temp;
				temp->pleft = pro->pleft;
				free(pro);
				pro = NULL;
			}
			else
			{
				while (temp->pleft != NULL)
				{
					pp = temp;
					temp = temp->pleft;
				}

				if(temp->pright == NULL)
				{
					pro->data = temp->data;
					pro->key = temp->key;
					free(temp);
					temp = NULL;
				}
				else
				{
					pp->pleft = temp->pright;
					pro->data = temp->data;
					pro->key = temp->key;
					free(temp);
					temp = NULL;
				}
			}
		}
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值