数据结构AVL树insert接口实现

Posted zhao111222333444

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构AVL树insert接口实现相关的知识,希望对你有一定的参考价值。

AVL树的插入接口需要分多种情况讨论,
前提是依据插入后平衡因子的值来做调整:

1.平衡因子为0,结束调整;
2.平衡因子为正负1,继续向上调整,直到0;
3.平衡因子为正负2,此时还需要进一步讨论:

出现平衡因子±2比较复杂,需要针对每一种情况做出不同旋转:

3.1. pParent的平衡因子为2,说明pParent的右子树高,设pParent的右子树的根为pSubR
当pSubR的平衡因子为1时,执行左单旋
当pSubR的平衡因子为-1时,执行右左双旋
3.2. pParent的平衡因子为-2,说明pParent的左子树高,设pParent的左子树的根为pSubL
当pSubL的平衡因子为-1是,执行右单旋
当pSubL的平衡因子为1时,执行左右双旋
旋转完成后,原pParent为根的子树个高度降低,已经平衡,不需要再向上更新。

#include<iostream>
using namespace std;
template<class T>
//AVLTree节点
class AVLNode
public:
	//AVL数有3个节点指针,1个val,1个平衡因子
	int _bf;
	T _val;
	AVLNode<T>* _partent;
	AVLNode<T>* _left;
	AVLNode<T>* _right;

	AVLNode(const T& val = T())//类0值
		:_bf(0)
		, _val(val)
		, _partent(nullptr)
		, _left(nullptr)
		, _right(nullptr)	
		
;
//AVLTree树
template<class T>
class AVLTree
public:
	typedef AVLNode<T> Node;

	bool insert(const T& val)
		//先判断是否为空树
		if (_root == nullptr)
			_root = new Node(val);
			return true;
		
		Node* node=_root;
		Node* partent=nullptr;
		while (node)
			partent = node;
			if (node->_val == val)
				return false;
			
			else if (node->_val > val)
				node = node->_left;
			
			else
				node = node->_right;
			
		
			//此时node在空上,并且没有链接父节点
			node = new Node(val);
			//此时链接父节点
			if (partent->_val>val)
				partent->_left = node;
			
			else
				partent->_right = node;
			
			node->_partent = partent;

			//开始调整bf
			//从partent开始
			while (partent)
				//先对父节点bf进行增或减
				if (partent->_left == node)
					--partent->_bf;
				else
					++partent->_bf;
				//根据调整后的bf操作
				//bf==0,结束调整
				//bf=+-1,继续向上更新
				//bf=+-2,需要旋转
				if (partent->_bf == 0)
					break;
				
				else if (partent->_bf == 1 || partent->_bf == -1)
					node = partent;
					partent = partent->_partent;
				
				else if(abs(partent->_bf)==2)
					if (node->_bf == -1 && partent->_bf == -2)
						//需要右旋
						RotateR(partent);
					
					else if (node->_bf == 1 && partent->_bf == 2)
						RotateL(partent);
					
					else if (partent->_bf == 2 && node->_bf == -1)
						Node* subRL = node->_left;
						int bf = subRL->_bf;
						RotateR(node);
						RotateL(partent);
						if (bf == 1)
							partent->_bf = -1;
							node->_bf = 0;
						
						else if (bf == -1)
							node->_bf = 1;
							partent->_bf = 0;

						
					
					else if (partent->_bf == -2 && node->_bf == 1)
						Node* subLR = node->_right;
						int bf = subLR->_bf;
						RotateL(node);
						RotateR(partent);
						if (bf == 1)
							partent->_bf = 0;
							node->_bf = -1;
						
						else if (bf == -1)
							node->_bf = 0;
							partent->_bf = 1;

						
					
					break;
				
			
		
		return true;
	
	//				partent              subL
	//subL                      ->				partent
	//		subLR							subLR								
	void RotateR(Node* partent)
		Node* subL = partent->_left;
		Node* subLR = subL->_right;
		subL->_right = partent;
		partent->_left = subLR;
		if (subLR)
			subLR->_partent = partent;
		

		
		//调整上部节点
		if (partent == _root)
			_root = subL;
			subL->_partent = nullptr;
		
		else
			Node* pparent = partent->_partent;
			if (pparent->_left == partent)
				pparent->_left = subL;
			else
				pparent->_right = subL;
			
			subL->_partent = pparent;
		
		partent->_partent = subL;
		subL->_bf = partent->_bf = 0;
	

	//partent                                     subR
	//            subR        ->	partent
	//		subRL							subRL								
	void RotateL(Node* partent)
		Node* subR = partent->_right;
		Node* subRL = subR->_left;
		subR->_left = partent;
		partent->_right = subRL;
		if (subRL)
			subRL->_partent = partent;
		

		partent->_partent = subR;
		//调整上部节点
		if (partent == _root)
			_root = subR;
			subR->_partent = nullptr;
		
		else
			Node* pparent = partent->_partent;
			if (pparent->_left == partent)
				pparent->_left = subR;
			
			else
				pparent->_right = subR;
			
			subR->_partent = pparent;
		
		subR->_bf = partent->_bf = 0;
	

	void _inorder(Node* root)
		if (root)
			_inorder(root->_left);
			cout << root->_val << " ";
			_inorder(root->_right);
		
	
	void inorder()
		return _inorder(_root);
	

	//检查AVL是否正确
	//查看节点长度
	int Height(Node* root)
		if (root == nullptr)
			return 0;
		
		int left = Height(root->_left);
		int right = Height(root->_right);
		return left > right ? left + 1 : right + 1;
	

	bool _isbalance(Node* root)
		if (root == nullptr)
			return true;
		
		int left = Height(root->_left);
		int right = Height(root->_right);
		if (right - left != root->_bf)
			cout << root->_val <<":错误"<< endl;
			return false;
		

		return abs(root->_bf) < 2 && _isbalance(root->_left) && _isbalance(root->_right);

	

	bool isbalance()
		return _isbalance(_root);
	
private:
	//记得置空
	AVLNode<T>* _root=nullptr;

;

void test()
	AVLTree<int> t;
	t.insert(5);
	t.insert(3);
	t.insert(1);
	t.insert(0);
	t.insert(2);
	t.insert(-1);
	t.insert(5);
	t.insert(1);
	t.inorder();
	cout << endl;
	cout<<t.isbalance();

int main()
	test();
	system("pause");
	return 0;

通过校验:

以上是关于数据结构AVL树insert接口实现的主要内容,如果未能解决你的问题,请参考以下文章

AVL树-平衡二叉树

初识C++之AVL树

数据结构54:平衡二叉树(AVL树)

平衡树AVL树

[javaSE] 数据结构(AVL树基本概念)

数据结构--AVL树