SBTree的概念以及代码实现

SBTree与AVL树具有相同的概念,也具有相同的操作类似自平衡,旋转操作和旋转的触发这三方面介绍SBTree

SBTree严格遵循下列公式,如有违反,则需要通过相应的转置操作来达到平衡

SIZE[right[t]] >= max(SIZE[left[left[t]]], SIZE[right[left[t]]]);

SIZE[left[t]] >= max(SIZE[left[right[t]]], SIZE[right[right[t]]])

其中SIZE[t]表示t结点所在的子树个数,且两个公式必须同时满足

SIZE[left[left[t]]]可以表示成t->left->left,SIZE[right[left[t]]])可表示成t->left->right

这两个公式可能有点难理解:简单来说就是每个结点所在的子树(分左子树和右子树)的结点个数不小于其兄弟的两个孩子所在子树的结点个数

比如说39这个结点,它的右子树结点个数为2,它的兄弟结点的左右子树个数最大值为1,2>1,成立

但是,它的左子树结点个数为0,0<1,不能同时满足两个公式

所以这里39要进行左旋操作

 

SBTree的调整方法:

(1)LL型:(SIZE[left[left[t]]] > size[right[t]])

这种情况种,左子树的左子树比右子树个数要大,会发生不平衡,

首先对子树进行右旋操作,旋转后对t的右子树进行调整,之后再对子树t进行调整

(2)LR型:(SIZE[right[left[t]]] > size[right[t]])

首先对t的左子树执行左旋操作,再对t进行右旋操作,之后分别调整结点t的左右子树,最终调整整条子树

(3)RR型:(SIZE[right[right[t]]] > size[left[t]])

首先对t的右子树进行左旋,然后分别进行调整

(4)RL型:(SIZE[left[right[t]]] > size[left[t]])

首先对右子树进行右旋操作,然后对左子树进行左旋操作

 

相关代码的实现

我们在二叉搜索树的基础上增加左旋,右旋,维护功能,就实现了一个SBTree

首先给出左旋算法,

SBTNode* mleft_rotate(SBTNode* node) {  //左旋操作
	SBTNode* temp = node->rchild;
	node->rchild = temp->lchild;
	temp->lchild->father = node;
	temp->lchild = node;
	temp->father = node->father;
	node->father = temp;

	return nullptr;
}

右旋算法与左旋算法类似:

SBTNode* mright_rotate(SBTNode* node) {  //右旋操作
	SBTNode* temp = node->lchild;
	node->lchild = temp->rchild;
	temp->rchild->father = node;
	temp->rchild = node;
	temp->father = node->father;
	node->father = temp;

	return nullptr;
}

这两个算法相对来说比较好理解,作为模板记下即可,在旋转过后,我们还要对结点进行维护操作

SBTree的调整与优化:

在插入后,一共有4种除法旋转的情况,分为LL型,LR型,RR型,RL型,RR型

在我们之前给出的公式种:

A:SIZE[right[t]] >= max(SIZE[left[left[t]]], SIZE[right[left[t]]]);

B:SIZE[left[t]] >= max(SIZE[left[right[t]]], SIZE[right[right[t]]]);

LL,LR违反了平衡条件A,RR和RL违反了平衡条件B

对应的,LL,LR能够保证b成立,RR,RL能够保证a成立,所以条件就可以这样进行筛选

 

维护算法如下:

(1)处理左子树更高的情况

   (1)LL型:右旋t

   (2)LR型:左旋t的左子树,再右旋t

(2)处理右子树更高的情况

   (1)RL型:右旋t的右子树,再左旋

   (2)RR型:左旋t

(3)递归进行相应的维护

  递归调整左子树中左子树的左子树更高的情况

  递归调整右子树中右子树的右子树更高的情况

  递归调整当前子树中左子树更高的情况

  递归调整当前子树中右子树更高的情况

template <typename Type>
SBTNode<Type>* maintain(SBTNode<Type>* node, bool flag) {
    
	if (flag == false) {
		if (node->lchild->lchild->size > node->rchild->size) {  //LL型树
			node = right_rotate(node);
		}
		else if (node->lchild->rchild->size > node->rchild->size) {  //LR型树
			node->lchild = left_rotate(node->lchild);
			node = right_rotate(node);
		}
		else {
			return node;  //正常结点,直接返回即可
		}
	}
	else {
		if (node->rchild->rchild->size > node->lchild->size) {  //RR型
			node = left_rotate(node);
		}
		else if (node->rchild->lchild->size > node->lchild->size) {
			node->rchild = right_rotate(node->rchild);
			node = left_rotate(node);
		}
		else {
			return node;
		}
	}

	node->lchild = maintain(node->lchild, false);
	node->rchild = maintain(node->rchild, true);
	
	maintain(node, false);
	maintain(node, true);
	
	return node;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值