C++ AVL tree (four kinds of rotation, insertion)

1. Concept and properties of AVL tree

AVL tree is also called height-balanced binary search tree. Its height is close to log[2]N (the logarithm of N with base 2). The shape of the entire tree is close to that of a complete binary tree. The
time complexity of adding, deleting, checking and modifying is O(log [2]N)
Insert image description here
In this section we implement the AVL tree of the Key-Value model

2. The general framework we want to achieve

1.Node definition of AVL tree

Here our AVL tree node has two more members than the ordinary binary tree node.
The first one is the balance factor. The balance factor we define here is the height of the right subtree - the height of the left subtree.
The second one points to the parent node. The pointer makes it easy to find the parent node and facilitate the implementation of rotation.

template<class K,class V>
struct AVLTreeNode
{
    
    
	AVLTreeNode(const pair<K,V>& data = pair<K,V>())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{
    
    }
	AVLTreeNode<K,V>* _pLeft;
	AVLTreeNode<K,V>* _pRight;
	AVLTreeNode<K,V>* _pParent;
	pair<K,V> _data;
	int _bf;   // 节点的平衡因子
};

The data type stored is a pair.
The first value of the pair is Key
and the second value is Value.

2.General framework of AVL tree

// AVL: 二叉搜索树 + 平衡因子的限制
template<class K,class V>
class AVLTree
{
    
    
	typedef AVLTreeNode<K,V> Node;
public:
	//构造函数
	AVLTree()
		: _pRoot(nullptr)
	{
    
    }

	// 在AVL树中插入值为data的节点
	bool Insert(const pair<K,V>& data);

	// AVL树的验证
	bool IsAVLTree()
	{
    
    
		return _IsAVLTree(_pRoot);
	}

	void InOrder()
	{
    
    
		_InOrder(_pRoot);
	}

private:
	//中序遍历
	void _InOrder(Node* root);

	// 根据AVL树的概念验证pRoot是否为有效的AVL树
	bool _IsAVLTree(Node* pRoot);

	//求树的高度
	size_t _Height(Node* pRoot);

	// 右单旋
	void RotateR(Node* pParent);

	// 左单旋
	void RotateL(Node* pParent);

	// 右左双旋
	void RotateRL(Node* pParent);

	// 左右双旋
	void RotateLR(Node* pParent);

private:
	Node* _pRoot;
};

3. Insert

The general logic of its insertion is very similar to the insertion logic of a binary search tree (BST). It
just needs to consider the modification and rotation of the balance factor.
Let's first write out the same parts as the binary search tree.

1. Insert the part whose logic is the same as that of BST

// 在AVL树中插入值为data的节点
bool Insert(const pair<K,V>& data)
{
    
    
	if (_pRoot == nullptr)
	{
    
    
		_pRoot = new Node(data);
		return true;
	}
	Node* cur = _pRoot, * parent = nullptr;
	//1.找插入位置
	while (cur)
	{
    
    
		if (cur->_data > data)
		{
    
    
			parent = cur;
			cur = cur->_pLeft;
		}
		else if (cur->_data < data)
		{
    
    
			parent = cur;
			cur = cur->_pRight;
		}
		else
		{
    
    
			return false;
		}
	}
	//2.new一个新节点,开始链接
	cur=new Node(data);
	//下面就是链接节点,修改平衡因子了,这也是AVL树相比于普通的BST的插入逻辑不同的地方
	return true;
}

2. Modify the balance factor

1. Preliminary instructions

First of all, we need to explain:
1. The balance factor of the newly inserted node is 0, which is initialized in the constructor of the AVL tree node.
2. During the process of inserting the node, we have always maintained the value of the balance factor as -1/0/ 1
3. Once the balance factor reaches 2 or -2, it means that the properties of the AVL tree are not satisfied at this time, and rotation is needed to adjust the balance factor to restore the balance factor to the state of -1/0/1

2. Drawing demonstration

Let's draw a picture to demonstrate the impact of inserting a node on the balance factor of the nodes in the entire tree.

1. Case 1 (affects all the way to the root node)

Insert image description here
Insert image description here
Insert image description here
Wouldn’t it be enough to just keep influencing upwards?
No, for example, the following situation

2. Case 2 (the influence disappears before affecting the root node)

For the convenience of demonstration, the value of node 8 is changed to 9 and
the newly inserted value is 8.

Insert image description here
Insert image description here

3. Deep profile situations 1 and 2

In the first case:
Insert image description here
Insert image description here
In the second case:
Insert image description here
Insert image description here

4. Summary

Insert image description here

3. Consider rotation

When modifying the balance factor, if the balance factor of a node changes to 2 or -2 after modification,
it means that the subtree with this node as the root node is no longer an AVL tree, and this node needs to be rotated.

We will introduce how to rotate later.
Here we first explain what kind of rotation is performed under what circumstances.

The rotation is divided into 4 situations:
1. Left single rotation

1. Introduction to left unirotation

Insert image description here
Insert image description here
Summarize:
Insert image description here

2. Introduction to right unilateral rotation

After understanding left unirotation, right unirotation can be well understood
Insert image description here
Insert image description here
. Summary:
Insert image description here

3. Introduction to right and left double rotation

The basic conditions for right and left double rotation are very similar to the basic conditions for left single rotation,
but there is one difference. Let’s take a look.
Insert image description here
Insert image description here

Insert image description here
Summarize:
Insert image description here

4. Introduction to left and right double rotation

In the same way, the basic conditions for left and right double rotation are very similar to right single rotation
Insert image description here
Insert image description here
Insert image description here
. Summary:
Insert image description here

5. Summary of rotation conditions:

Insert image description here

4. Improvement of insertion logic

So we can write insert code like this

// 在AVL树中插入值为data的节点
bool Insert(const pair<K,V>& data)
{
    
    
	if (_pRoot == nullptr)
	{
    
    
		_pRoot = new Node(data);
		return true;
	}
	Node* cur = _pRoot, * parent = nullptr;
	//1.找插入位置
	while (cur)
	{
    
    
		if (cur->_data > data)
		{
    
    
			parent = cur;
			cur = cur->_pLeft;
		}
		else if (cur->_data < data)
		{
    
    
			parent = cur;
			cur = cur->_pRight;
		}
		else
		{
    
    
			return false;
		}
	}
	//2.插入节点调整平衡因子
	cur = new Node(data);
	//在parent左边插入节点
	if (parent->_data > data)
	{
    
    
		parent->_pLeft = cur;
		parent->_bf--;
	}
	//在parent的右边插入节点
	else
	{
    
    
		parent->_pRight = cur;
		parent->_bf++;
	}
	cur->_pParent = parent;
	//3.向上影响平衡因子
	//影响的结束条件:
	//1.cur到达_pRoot,也就是parent到达nullptr
	//2.parent的bf调整之后变为0
	//因为0只能由1或者-1变过来
	//而且由1或者-1变成0时,parent这个树的高度没有发生变化,因此不会在往上去影响了
	//3.parent这棵树需要旋转
	//旋转之后会达到1个目的:
	//降低parent这棵树的高度,降为插入这个结点之前的高度
	//因此此时就不会在往上去影响了
	while (parent)
	{
    
    
		//此时无需在往上去影响
		if (parent->_bf == 0)
		{
    
    
			break;
		}
		//此时需要再往上去影响
		//因为1或者-1只能由0变过来,因此parent这个树的高度变高,需要往上去影响
		else if (parent->_bf == 1 || parent->_bf == -1)
		{
    
    
			cur = parent;
			parent = parent->_pParent;
			if (parent != nullptr)
			{
    
    
				//说明parent是左子树,因此会让祖父的bf--
				if (parent->_pLeft == cur)
				{
    
    
					parent->_bf--;
				}
				//说明parent是右子树,因此会让祖父的bf++
				else
				{
    
    
					parent->_bf++;
				}
			}
		}
		else if (parent->_bf == 2 || parent->_bf == -2)
		{
    
    
			//左单旋
			if (parent->_bf == 2 && cur->_bf == 1)
			{
    
    
				RotateL(parent);
			}
			//右左双旋
			else if (parent->_bf == 2 && cur->_bf == -1)
			{
    
    
				RotateRL(parent);
			}
			//右单旋
			else if (parent->_bf == -2 && cur->_bf == -1)
			{
    
    
				RotateR(parent);
			}
			//左右双旋
			else if (parent->_bf == -2 && cur->_bf == 1)
			{
    
    
				RotateLR(parent);
			}
			break;
		}
		else
		{
    
    
			assert(false);
		}
	}
	return true;
}

4. Rotation animation demonstration and code implementation

We have already introduced above what are left and right single rotation, right left, left and right double rotation.
Now let’s take a look at how to achieve rotation?

1. Left single rotation

1. Steps + Precautions

Insert image description here

2. Animation demonstration

Before rotation:
Insert image description here
During rotation:
Insert image description here
After rotation is completed
Insert image description here

3. Code implementation

// 左单旋
void RotateL(Node* pParent)
{
    
    
	Node* subR = pParent->_pRight;
	Node* subRL = subR->_pLeft;
	Node* grandParent = pParent->_pParent;
	pParent->_pParent = subR;
	subR->_pLeft = pParent;
	pParent->_pRight = subRL;
	if (subRL)
		subRL->_pParent = pParent;
	//说明此时pParent是_pRoot
	if (grandParent == nullptr)
	{
    
    
		_pRoot = subR;
		_pRoot->_pParent = nullptr;
	}
	//说明此时pParent所在的树是一颗子树,需要跟父亲链接
	else
	{
    
    
		if (pParent == grandParent->_pLeft)
		{
    
    
			grandParent->_pLeft = subR;
		}
		else
		{
    
    
			grandParent->_pRight = subR;
		}
		subR->_pParent = grandParent;
	}
	//调整平衡因子
	pParent->_bf = subR->_bf = 0;
}

2. Right single rotation

In the same way, the same idea is used for right-hand single rotation
, and the precautions are exactly the same as for left-hand single rotation.

1. Animation demonstration

Before the rotation:
Insert image description here
During the rotation:
Insert image description here
After the rotation is completed:
Insert image description here

2. Code implementation

// 右单旋
void RotateR(Node* pParent)
{
    
    
	Node* subL = pParent->_pLeft;
	Node* subLR = subL->_pRight;
	Node* grandParent = pParent->_pParent;
	subL->_pRight = pParent;
	pParent->_pParent = subL;
	pParent->_pLeft = subLR;
	if (subLR)
		subLR->_pParent = pParent;
	if (grandParent == nullptr)
	{
    
    
		_pRoot = subL;
		_pRoot->_pParent = nullptr;
	}
	else
	{
    
    
		if (pParent == grandParent->_pLeft)
		{
    
    
			grandParent->_pLeft = subL;
		}
		else
		{
    
    
			grandParent->_pRight = subL;
		}
		subL->_pParent = grandParent;
	}
	//修改平衡因子
	subL->_bf = pParent->_bf = 0;
}

3.Right and left double rotation

Right-left double rotation and left-right double rotation are the reuse of left single rotation and right single rotation, so I won’t go into details here.
Just go to the animation for demonstration.

1. Turn right first

Before rotation:
Insert image description here
During rotation:
Insert image description here
After rotation:
Insert image description here

2. Turn left again

Before rotation:
Insert image description here
During rotation:
Insert image description here
After rotation:
Insert image description here

3. Code implementation

// 右左双旋
void RotateRL(Node* pParent)
{
    
    
	Node* subR = pParent->_pRight;
	Node* subRL = subR->_pLeft;
	int bf = subRL->_bf;
	//对subR进行一次右旋
	RotateR(subR);
	//在对pParent进行一次左旋
	RotateL(pParent);
	//这两次旋转达到了一个目的:把subRL的左子树给pParent成为pParent的右子树
	//把subRL的右子树给subR成为subR的左子树

	//根据旋转前subRL的平衡因子调整平衡后的平衡因子
	if (bf == 0)
	{
    
    
		subR->_bf = pParent->_bf = subRL->_bf = 0;
	}
	//说明subRL的左子树更低
	else if (bf == 1)
	{
    
    
		pParent->_bf = -1;
		subR->_bf = subRL->_bf = 0;
	}
	else if (bf == -1)
	{
    
    
		subR->_bf = 1;
		pParent->_bf = subRL->_bf = 0;
	}
	else
	{
    
    
		assert(false);
	}
}

4. Double left and right rotation

1. Turn left first

Before rotation:
Insert image description here
During rotation:
Insert image description here
After rotation:
Insert image description here

2. Turn right again

Before rotation:
Insert image description here
During rotation:
Insert image description here
After rotation:
Insert image description here

3. Code implementation

// 左右双旋
void RotateLR(Node* pParent)
{
    
    
	Node* subL = pParent->_pLeft;
	Node* subLR = subL->_pRight;
	int bf = subLR->_bf;
	RotateL(subL);
	RotateR(pParent);
	//旋转的过程就是把subLR的左子树给subL成为subL的右子树
	//把subLR的右子树给pParent成为pParent的左子树
	if (bf == 0)
	{
    
    
		subL->_bf = subLR->_bf = pParent->_bf = 0;
	}
	else if (bf == 1)
	{
    
    
		subL->_bf = -1;
		subLR->_bf = pParent->_bf = 0;
	}
	else if (bf == -1)
	{
    
    
		pParent->_bf = 1;
		subL->_bf = subLR->_bf = 0;
	}
	else
	{
    
    
		assert(false);
	}
}

5. Verification of AVL tree

In order to verify the correctness of the AVL tree,
we add in-order traversal code, height finding code, and verify that the height difference between the left and right subtrees is not greater than 1.

// AVL树的验证
bool IsAVLTree()
{
    
    
	return _IsAVLTree(_pRoot);
}

void InOrder()
{
    
    
	_InOrder(_pRoot);
}

private:
void _InOrder(Node* root)
{
    
    
	if (root == nullptr) return;
	_InOrder(root->_pLeft);
	cout << root->_data.first << " " << root->_data.second << " ";
	_InOrder(root->_pRight);
}

// 根据AVL树的概念验证pRoot是否为有效的AVL树
bool _IsAVLTree(Node* pRoot)
{
    
    
	if (pRoot == nullptr) return true;
	int leftHeight = _Height(pRoot->_pLeft);
	int rightHeight = _Height(pRoot->_pRight);
	return abs(leftHeight - rightHeight) < 2 && _IsAVLTree(pRoot->_pLeft) && _IsAVLTree(pRoot->_pRight);
}

size_t _Height(Node* pRoot)
{
    
    
	if (pRoot == nullptr)
	{
    
    
		return 0;
	}
	int leftHeight = _Height(pRoot->_pLeft);
	int rightHeight = _Height(pRoot->_pRight);
	return max(leftHeight, rightHeight) + 1;
}

Below is the test code

#include "AVLTree.h"
#include <vector>
int test1()
{
    
    
	//int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
	int a[] = {
    
     4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
	AVLTree<int,string> tree;
	for (auto& e : a)
	{
    
    
		cout << e << " : " << tree.Insert(make_pair(e,"wzs")) << endl;
	}
	cout << endl;
	tree.InOrder();
	cout << endl;
	cout << tree.IsAVLTree() << endl;
	return 0;
}
int test2()
{
    
    
	const int N = 300000;
	vector<int> v;
	v.reserve(N);
	srand(time(0));

	for (size_t i = 0; i < N; i++)
	{
    
    
		v.push_back(rand() + i);
		//cout << v.back() << endl;
	}

	AVLTree<int,int> t;
	for (auto e : v)
	{
    
    
		if (e == 14604)
		{
    
    
			int x = 0;
		}

		t.Insert(make_pair(e,e));
		//cout << "Insert:" << e << "->" << t.IsAVLTree()<< endl;
	}

	cout << t.IsAVLTree() << endl;

	return 0;
}

Insert image description here
Verification successful

6. Complete code

1.AVLTree.h:

#pragma once
#include <iostream>
using namespace std;
#include <assert.h>

template<class K,class V>
struct AVLTreeNode
{
    
    
	AVLTreeNode(const pair<K,V>& data = pair<K,V>())
		: _pLeft(nullptr)
		, _pRight(nullptr)
		, _pParent(nullptr)
		, _data(data)
		, _bf(0)
	{
    
    }
	AVLTreeNode<K,V>* _pLeft;
	AVLTreeNode<K,V>* _pRight;
	AVLTreeNode<K,V>* _pParent;
	pair<K,V> _data;
	int _bf;   // 节点的平衡因子
};


// AVL: 二叉搜索树 + 平衡因子的限制
template<class K,class V>
class AVLTree
{
    
    
	typedef AVLTreeNode<K,V> Node;
public:
	AVLTree()
		: _pRoot(nullptr)
	{
    
    }

	// 在AVL树中插入值为data的节点
	bool Insert(const pair<K,V>& data)
	{
    
    
		if (_pRoot == nullptr)
		{
    
    
			_pRoot = new Node(data);
			return true;
		}
		Node* cur = _pRoot, * parent = nullptr;
		//1.找插入位置
		while (cur)
		{
    
    
			if (cur->_data > data)
			{
    
    
				parent = cur;
				cur = cur->_pLeft;
			}
			else if (cur->_data < data)
			{
    
    
				parent = cur;
				cur = cur->_pRight;
			}
			else
			{
    
    
				return false;
			}
		}
		//2.插入节点调整平衡因子
		cur = new Node(data);
		//在parent左边插入节点
		if (parent->_data > data)
		{
    
    
			parent->_pLeft = cur;
			parent->_bf--;
		}
		//在parent的右边插入节点
		else
		{
    
    
			parent->_pRight = cur;
			parent->_bf++;
		}
		cur->_pParent = parent;
		//3.向上影响平衡因子
		//影响的结束条件:
		//1.cur到达_pRoot,也就是parent到达nullptr
		//2.parent的bf调整之后变为0
		//因为0只能由1或者-1变过来
		//而且由1或者-1变成0时,parent这个树的高度没有发生变化,因此不会在往上去影响了
		//3.parent这棵树需要旋转
		//旋转之后会达到1个目的:
		//降低parent这棵树的高度,降为插入这个结点之前的高度
		//因此此时就不会在往上去影响了
		while (parent)
		{
    
    
			//此时无需在往上去影响
			if (parent->_bf == 0)
			{
    
    
				break;
			}
			//此时需要再往上去影响
			//因为1或者-1只能由0变过来,因此parent这个树的高度变高,需要往上去影响
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
    
    
				cur = parent;
				parent = parent->_pParent;
				if (parent != nullptr)
				{
    
    
					//说明parent是左子树,因此会让祖父的bf--
					if (parent->_pLeft == cur)
					{
    
    
						parent->_bf--;
					}
					//说明parent是右子树,因此会让祖父的bf++
					else
					{
    
    
						parent->_bf++;
					}
				}
			}
			else if (parent->_bf == 2 || parent->_bf == -2)
			{
    
    
				//左单旋
				if (parent->_bf == 2 && cur->_bf == 1)
				{
    
    
					RotateL(parent);
				}
				//右左双旋
				else if (parent->_bf == 2 && cur->_bf == -1)
				{
    
    
					RotateRL(parent);
				}
				//右单旋
				else if (parent->_bf == -2 && cur->_bf == -1)
				{
    
    
					RotateR(parent);
				}
				//左右双旋
				else if (parent->_bf == -2 && cur->_bf == 1)
				{
    
    
					RotateLR(parent);
				}
				break;
			}
			else
			{
    
    
				assert(false);
			}
		}
		return true;
	}

	// AVL树的验证
	bool IsAVLTree()
	{
    
    
		return _IsAVLTree(_pRoot);
	}

	void InOrder()
	{
    
    
		_InOrder(_pRoot);
	}

private:
	void _InOrder(Node* root)
	{
    
    
		if (root == nullptr) return;
		_InOrder(root->_pLeft);
		cout << root->_data.first << " " << root->_data.second << " ";
		_InOrder(root->_pRight);
	}

	// 根据AVL树的概念验证pRoot是否为有效的AVL树
	bool _IsAVLTree(Node* pRoot)
	{
    
    
		if (pRoot == nullptr) return true;
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		return abs(leftHeight - rightHeight) < 2 && _IsAVLTree(pRoot->_pLeft) && _IsAVLTree(pRoot->_pRight);
	}

	size_t _Height(Node* pRoot)
	{
    
    
		if (pRoot == nullptr)
		{
    
    
			return 0;
		}
		int leftHeight = _Height(pRoot->_pLeft);
		int rightHeight = _Height(pRoot->_pRight);
		return max(leftHeight, rightHeight) + 1;
	}

	// 右单旋
	void RotateR(Node* pParent)
	{
    
    
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		Node* grandParent = pParent->_pParent;
		subL->_pRight = pParent;
		pParent->_pParent = subL;
		pParent->_pLeft = subLR;
		if (subLR)
			subLR->_pParent = pParent;
		if (grandParent == nullptr)
		{
    
    
			_pRoot = subL;
			_pRoot->_pParent = nullptr;
		}
		else
		{
    
    
			if (pParent == grandParent->_pLeft)
			{
    
    
				grandParent->_pLeft = subL;
			}
			else
			{
    
    
				grandParent->_pRight = subL;
			}
			subL->_pParent = grandParent;
		}
		//修改平衡因子
		subL->_bf = pParent->_bf = 0;
	}

	// 左单旋
	void RotateL(Node* pParent)
	{
    
    
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;
		Node* grandParent = pParent->_pParent;
		pParent->_pParent = subR;
		subR->_pLeft = pParent;
		pParent->_pRight = subRL;
		if (subRL)
			subRL->_pParent = pParent;
		//说明此时pParent是_pRoot
		if (grandParent == nullptr)
		{
    
    
			_pRoot = subR;
			_pRoot->_pParent = nullptr;
		}
		//说明此时pParent所在的树是一颗子树,需要跟父亲链接
		else
		{
    
    
			if (pParent == grandParent->_pLeft)
			{
    
    
				grandParent->_pLeft = subR;
			}
			else
			{
    
    
				grandParent->_pRight = subR;
			}
			subR->_pParent = grandParent;
		}
		//调整平衡因子
		pParent->_bf = subR->_bf = 0;
	}

	// 右左双旋
	void RotateRL(Node* pParent)
	{
    
    
		Node* subR = pParent->_pRight;
		Node* subRL = subR->_pLeft;
		int bf = subRL->_bf;
		//对subR进行一次右旋
		RotateR(subR);
		//在对pParent进行一次左旋
		RotateL(pParent);
		//这两次旋转达到了一个目的:把subRL的左子树给pParent成为pParent的右子树
		//把subRL的右子树给subR成为subR的左子树

		//根据旋转前subRL的平衡因子调整平衡后的平衡因子
		if (bf == 0)
		{
    
    
			subR->_bf = pParent->_bf = subRL->_bf = 0;
		}
		//说明subRL的左子树更低
		else if (bf == 1)
		{
    
    
			pParent->_bf = -1;
			subR->_bf = subRL->_bf = 0;
		}
		else if (bf == -1)
		{
    
    
			subR->_bf = 1;
			pParent->_bf = subRL->_bf = 0;
		}
		else
		{
    
    
			assert(false);
		}
	}

	// 左右双旋
	void RotateLR(Node* pParent)
	{
    
    
		Node* subL = pParent->_pLeft;
		Node* subLR = subL->_pRight;
		int bf = subLR->_bf;
		RotateL(subL);
		RotateR(pParent);
		//旋转的过程就是把subLR的左子树给subL成为subL的右子树
		//把subLR的右子树给pParent成为pParent的左子树
		if (bf == 0)
		{
    
    
			subL->_bf = subLR->_bf = pParent->_bf = 0;
		}
		else if (bf == 1)
		{
    
    
			subL->_bf = -1;
			subLR->_bf = pParent->_bf = 0;
		}
		else if (bf == -1)
		{
    
    
			pParent->_bf = 1;
			subL->_bf = subLR->_bf = 0;
		}
		else
		{
    
    
			assert(false);
		}
	}

private:
	Node* _pRoot;
};

2.test.cpp

#include "AVLTree.h"
#include <vector>
int test1()
{
    
    
	//int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
	int a[] = {
    
     4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
	AVLTree<int,string> tree;
	for (auto& e : a)
	{
    
    
		cout << e << " : " << tree.Insert(make_pair(e,"wzs")) << endl;
	}
	cout << endl;
	tree.InOrder();
	cout << endl;
	cout << tree.IsAVLTree() << endl;
	return 0;
}

int test2()
{
    
    
	const int N = 300000;
	vector<int> v;
	v.reserve(N);
	srand(time(0));

	for (size_t i = 0; i < N; i++)
	{
    
    
		v.push_back(rand() + i);
		//cout << v.back() << endl;
	}

	AVLTree<int,int> t;
	for (auto e : v)
	{
    
    
		if (e == 14604)
		{
    
    
			int x = 0;
		}

		t.Insert(make_pair(e,e));
		//cout << "Insert:" << e << "->" << t.IsAVLTree()<< endl;
	}

	cout << t.IsAVLTree() << endl;

	return 0;
}

int main()
{
    
    
	test1();
	cout << "=============    开始test2的验证   =================" << endl;
	test2();
	return 0;
}

The above is the entire content of C++ AVL tree (four kinds of rotation, insertion), I hope it can be helpful to everyone!

Guess you like

Origin blog.csdn.net/Wzs040810/article/details/135099616