数据结构---二叉树(2)---平衡二叉树(5 删除)

0.简介

删除平衡二叉树的结点也需要仔细的研究一下。还有代码上对上一篇打了些补丁

1.删除

删除结点后的结构一般有两种,一类是删除后不平衡了,一类是删除后仍然平衡。这两类别目前对我们来说,没有什么区别,因为前面已经研究过结点平衡调整的方法,所以可以直接在这里使用,那么需要研究的就是如何删除结点。

我们先从链表的角度来看,链表删除比较容易,改变指向下一个结点的指针就好,一般来说,改变一个就可以。

链表删除

二叉树来说,删除就麻烦了一些,要有两个指针需要变化,链表只需要考虑下一个元素怎么连接上就好,树要考虑子节点谁来连接。

二叉树删除结点

我们考虑让子节点的任意一个来接替位置,我们就一律让右边的结点来接替父节点的位置,左节点保持不动,若没有右结点,在去升左结点的位置。

结点换位

结点换位就要调整指针,这里为了方便,可以用另一种办法,先考虑如下问题,如何删除单链表中指针正在指向的元素,不需要额外变量,只需要将当前结点的下一个结点的内容复制过来,然后删除下一个结点即可。树中我也这么做。

删除的流程如下

1.找到要删除的结点

2.将其删除,并且移动相关结点数据

3.查看树是否保持平衡,不平衡则调整。

2.实现

#include<iostream>
#include <algorithm>

using namespace std;
struct TreeNode
{
	TreeNode(){}
	TreeNode(int n,int h):num(n),height(h) {}
	int num = 0;
	int height = 0;
	TreeNode* left = nullptr;
	TreeNode* right = nullptr;
	TreeNode* parent = nullptr;
};

inline int getHeight(TreeNode* root)
{
	return root ? root->height : 0;
}

//调整平衡后树高度
void adjustHeight(TreeNode*T)
{
	if (T->left != nullptr && T->right != nullptr)
		T->height = max(T->left->height + 1, T->right->height + 1);
	else if (T->left != nullptr)
		T->height = T->left->height + 1;
	else if (T->right != nullptr)
		T->height = T->right->height + 1;
	else
		T->height = 1;
}

void condition1(TreeNode*& root)
{
	/*   A
	    /
	   B
	  /
	 C
	*/
	TreeNode* A = root;
	TreeNode* B = root->left;

	A->left = B->right;
	B->parent = A->parent;
	A->parent = B;
	B->right = A;
	root = B;
	//重新计算平衡后,被调整结点的高度记录
	adjustHeight(A);
	adjustHeight(B);
}

void condition2(TreeNode*& root)
{
	/*A
	   \
	    B
		 \
		  C
	*/
	TreeNode* A = root;
	TreeNode* B = root->right;

	A->right = B->left;
	B->parent = A->parent;
	A->parent = B;
	B->left = A;

	root = B;
	adjustHeight(A);
	adjustHeight(B);
}

void condition3(TreeNode*& root)
{
	/*   A
		/
	   B
	    \
	     C
	*/
	TreeNode* A = root;
	TreeNode* B = root->left;
	TreeNode* C = root->left->right;
	
	A->left = C->right;
	B->right = C->left;
	C->left = B;
	C->right = A;
	C->parent = A->parent;
	B->parent = C;
	A->parent = A;

	root = C;
	adjustHeight(A);
	adjustHeight(B);
	adjustHeight(C);
}

void condition4(TreeNode*& root)
{
	/*   A
		   \
	        B
		   /
		 C
	*/
	TreeNode* A = root;
	TreeNode* B = root->right;
	TreeNode* C = root->right->left;

	A->right = C->left;
	B->left = C->right;
	C->right = B;
	C->left = A;
	C->parent = A->parent;
	B->parent = C;
	A->parent = A;

	root = C;
	adjustHeight(A);
	adjustHeight(B);
	adjustHeight(C);
}

int addNode(TreeNode* &root,int num)
{
	//如果节点的空
	if (root == nullptr)
	{
		//创建节点
		root = new TreeNode(num,1);
		//返回树高
		return 1;
	}
	int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
	//左子树
	if (num < root->num)
	{
		//添加节点
		lHeight = addNode(root->left, num);
		//修改父节点
		root->left->parent = root;
	}
	//右子树
	else
	{
		//添加节点
		rHeight = addNode(root->right, num);
		//修改父节点
		root->right->parent = root;
	}

	//调整树
	if (abs(lHeight - rHeight) > 1)
	{
		if (lHeight> rHeight)
		{
			if (getHeight(root->left->left) > getHeight(root->left->right))
				condition1(root);
			else
				condition3(root);
		}
		else
		{
			if (getHeight(root->right->right) > getHeight(root->right->left))
				condition2(root);
			else
				condition4(root);
		}
	}
	lHeight = getHeight(root->left);
	rHeight = getHeight(root->right);
	return root->height = max(lHeight , rHeight) + 1;
}

int moveNode(TreeNode*& root)
{
	if (root == nullptr)
		return 0;
	TreeNode*& parent = root;
	int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
	if (root->left != nullptr || root->right != nullptr)
	{
		//将右边提上来,没有右边就提左边
		
		if (root->right != nullptr)
		{
			root->num = root->right->num;
			rHeight = moveNode(root->right);

		}
		else if (root->left != nullptr)
		{
			root->num = root->left->num;
			lHeight = moveNode(root->left);
		}
		return root->height = max(rHeight, lHeight) + 1;
	}
	else
	{
		//删除parent
		if (parent != nullptr)
		{
			delete parent;
			parent = nullptr;
			return 0;
		}
	}
}

int deleteNode(TreeNode*& root, int num)
{
	if (root == nullptr)
		return 0;
	//删除
	TreeNode* parent = nullptr;
	//获取当前树的高度
	int lHeight = getHeight(root->left), rHeight = getHeight(root->right);
	if (num > root->num)
		rHeight = deleteNode(root->right,num);
	else if (num < root->num)
		lHeight = deleteNode(root->left, num);
	else if (root->num == num)
		moveNode(root);


	//调整树
	if (abs(lHeight - rHeight) > 1)
	{
		if (lHeight > rHeight)
		{
			if (getHeight(root->left->left) > getHeight(root->left->right))
				condition1(root);
			else
				condition3(root);
		}
		else
		{
			if (getHeight(root->right->right) > getHeight(root->right->left))
				condition2(root);
			else
				condition4(root);
		}
	}

	//重新计算树的高度
	if (root != nullptr)
	{
		lHeight = getHeight(root->left);
		rHeight = getHeight(root->right);
		return root->height = max(lHeight, rHeight) + 1;
	}
	else
	{
		lHeight = 0;
		rHeight = 0;
		return 0;
	}
	
	
}
int main()
{
	TreeNode* root = nullptr;
	addNode(root,12);
	addNode(root, 5);
	addNode(root, 15);
	addNode(root,3);
	addNode(root, 8);
	addNode(root, 9);
	addNode(root, 6);
	addNode(root, 20);
	//addNode(root, 21);
	
	deleteNode(root, 20);
	deleteNode(root, 15);
	deleteNode(root, 9);
	deleteNode(root, 12);
	deleteNode(root, 3);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值