C++avltree

Posted by 川川的博客 on May 18, 2025

AVLTree

  • 规定平衡因子 = 右子树高度 - 左子树高度
  • 更新平衡因子
  • 平衡因子>1或<-1,需要旋转调整

image-20250623223742943

image-20250623225515233

image-20250623225423253

image-20250623225953303

bool insert(const K& key) {

	if (_root == nullptr) {
		_root->_data = key;
		return true;
	}

	Node* cur = _root;
	Node* parent = nullptr;
	while (cur) {

		if (cur->_data > key) {
			cur = cur->_left;
			parent = cur;
		}
		else if(cur->_data<key){
			cur = cur->_right;
			parent = cur;
		}
		else {
			return false;
		}
	}
	cur = new Node(key);
	//把cur链接上,判断是左还是右孩子
	if (parent->_date > key) {
		parent->_left = cur;
		cur->_parent = parent;
		
	}
	else {
		parent->_right = cur;
		cur->_parent = parent;
	}

	//更新父亲平衡因子,需要向上检测父亲平衡因子是否符合规则
	while (parent) {

		//平衡因子只能从下往上更新
		if (parent->_left = cur) {
			parent->_bf--;
		}
		else {
			parent->_bf++;
		}


		if (parent->_bf == 0) {
			break;
		}
		else if(parent->_bf==1||parent->_bf==-1){
			//说明父亲结点之前平衡因子是0,需要向上更新
			cur = parent;
			parent = cur->_parent;
		}
		else if(parent->_bf==2||parent->_bf==-2){
			//说明父亲结点平衡因子是2或-2违反平衡性
			if (parent->_bf == 2) {
				if (cur->_bf == 1) {
					_RotateL(parent);
				}
				else if (cur->_bf == -1) {
					_RotateRL(parent);
				}

			}
			else if(parent->_bf == -2) {
				if (cur->_bf == -1) {
					_RotateR(parent);
				}
				else if (cur->_bf == 1) {
					_RotateLR(parent);

				}


			}
		}


		break;
	}

	return true;

}

AVL树旋转

左单旋image-20250624235957193

void RotateL(Node* parent) {
	Node* subR = parent->_right;
	Node* subRL = subR->_left;

	parent->_right = subRL;
	if (subRL) {
		subRL->_parent = parent;
	}

	subR->_left = parent;
	//父亲结点可能是子树,记录祖父
	Node* pparent = parent->_parent;
	parent->_parent = subR;
	subR->_parent = pparent;
	//如果parent是根节点
	if (pparent == NULL) {
		_root = subR;
	}
	else {
		if (pparent->_left == parent) {
			pparent->_left = subR;
		}
		else {
			pparent->_right = subR;
		}
	}

	//subR和parent的平衡因子变为0
	subR->_bf = parent->_bf = 0;
}

右单旋

image-20250625000021882

void RotateR(Node* parent) {
	Node* subL = parent->_left;
	Node* subLR = subL->_right;

	parent->_left = subLR;
	if (subLR) {
		subLR->_parent = parent;
	}

	subL->_right = parent;
	//因为parent可能是子树,记录parent的父亲
	Node* pparent = parent->_parent;
	
	parent->_parent = subL;
	subL->_parent = pparent;

	//panrent是根节点
	if (pparent == NULL) {
		_root = subL;
	}
	else 
	{
		if (pparent->_left == parent) {
			pparent->_left = subL;
		}
		else {
			pparent->_right = subL;
		}
	}
	//subL和parent的平衡因子变为0
	subL->_bf = parent->_bf = 0;
}

左右双旋

image-20250625000144210

void _RotateLR(Node* parent) {

	Node* subL = parent->_left;
	Node* subLR = subL->_right;

	//旋转之前记录subLR的平衡因子,用来修改旋转后subL和parent平衡因子
	int bf = subLR->_bf;

	_RotateL(subL);
	_RotateR(parent);
	if (bf == 1) {
		subL->_bf = -1;
	}
	else {
		parent->_bf = 1;
	}

}

右左双旋

image-20250625000255186

void _RotateRL(Node* parent) {

	Node* subR = parent->_right;
	Node* subRL = subR->_left;

	//旋转之前记录subRL的平衡因子,用来修改旋转后subR和parent平衡因子
	int bf = subRL->_bf;

	_RotateR(subR);
	_RotateL(parent);
	if (bf == 1) {
		subR->_bf = 0;
		parent->_bf = -1;
	}
	else {
		subR->_bf = 1;
		parent->_bf = 0;
	}

}

image-20250625220751715