AVL树(平衡二叉树)图解-创新互联

文章目录
  • 左左型
  • 右右型
  • 左右型
  • 右左型
  • 测试及完整代码

成都创新互联专注于高邮网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供高邮营销型网站建设,高邮网站制作、高邮网页设计、高邮网站官网定制、小程序制作服务,打造高邮网络公司原创品牌,更为您提供高邮网站排名全网营销落地服务。

本节我们不会主要讲解AVL树的原理,只讨论AVL树的四种旋转的情形,有关AVL树的基本知识请看其他博客。

左左型


在这里插入图片描述

对于左左型的AVL树,我们只需对它进行一次左旋即可:

void AVLTree::SingleRotateWithLeft(TreeNode*& root)
{//左左型
	TreeNode* K2 = root;

	TreeNode* K1 = K2->left;
	K2->left = K1->right;
	K1->right = K2;
	//K1经过旋转后成为了新的根节点,K2是其右孩子

	K2->height = max(Height(K2->left), Height(K2->right)) + 1;
	K1->height = max(Height(K1->left), K2->height) + 1;

	root = K1;	//根节点重新确认
}

右右型

在这里插入图片描述
在这里插入图片描述

对于右右型的AVL树,我们只需对它进行一次左旋即可:

void AVLTree::SingleRotateWithRight(TreeNode*& root)
{//右右型
	TreeNode* K1 = root;

	TreeNode* K2 = K1->right;
	K1->right = K2->left;
	K2->left = K1;
	//K1经过旋转后成为了新的根节点,K2是其左孩子

	K1->height = max(Height(K1->left), Height(K1->right)) + 1;
	K2->height = max(K1->height, Height(K2->right)) + 1;

	root = K2;
}

左右型

在这里插入图片描述
在这里插入图片描述
对于左右型的AVL树,我们只需对它进行一次右旋,然后进行一次左旋即可:

void AVLTree::DoubleRotateWithLeft(TreeNode*& root)
{//左右型
	TreeNode* K3 = root;
	//1. 先右旋
	SingleRotateWithRight(K3->left);
	//2. 后左旋
	SingleRotateWithLeft(K3);

	root = K3;
}

右左型

在这里插入图片描述
在这里插入图片描述
对于右左型的AVL树,我们只需对它进行一次左旋,然后进行一次右旋即可:

void AVLTree::DoubleRotateWithRight(TreeNode*& root)
{//右左型
	TreeNode* K3 = root;
	//1. 先左旋
	SingleRotateWithLeft(K3->right);
	//2. 再右旋
	SingleRotateWithRight(K3);

	root = K3;
}

测试及完整代码
#includeusing namespace std;

using Type = int;

struct TreeNode
{Type data;
	TreeNode* left;
	TreeNode* right;
	int height = 0;
	TreeNode(const Type& data, TreeNode* left = nullptr, TreeNode* right = nullptr, const int& height = 0)
		:data(data), left(left), right(right),height(height) {}
};

class AVLTree
{public:
	AVLTree();
	~AVLTree();
	//计算AVL树的节点高度
	static int Height(TreeNode* node);
	void insert(const Type& data);
private:
	void SingleRotateWithLeft(TreeNode*& root);
	void SingleRotateWithRight(TreeNode*& root);
	void DoubleRotateWithLeft(TreeNode*& root);
	void DoubleRotateWithRight(TreeNode*& root);
	void _insert(const Type& data, TreeNode*& root);
private:
	TreeNode* root;
};

int main()
{AVLTree t1, t2, t3, t4;

	//右右型
	t1.insert(1);
	t1.insert(2);
	t1.insert(3);

	//左左型
	t2.insert(3);
	t2.insert(2);
	t2.insert(1);

	//左右型
	t3.insert(3);
	t3.insert(1);
	t3.insert(2);

	//右左型
	t4.insert(1);
	t4.insert(3);
	t4.insert(2);

	AVLTree t;
	vectorvec{4,2,6,1,3,5,7,16,15,14,13,12,11,10,8,9 };
	for (int i = 0; i< vec.size(); i++)
	{t.insert(vec[i]);
	}
	return 0;
}

AVLTree::AVLTree()
{root = nullptr;
}

AVLTree::~AVLTree()
{//销毁整棵树
}

int AVLTree::Height(TreeNode* node)
{if (node == nullptr)
	{return -1;
	}
	else
	{return node->height;
	}
}

void AVLTree::insert(const Type& data)
{_insert(data, root);
}

void AVLTree::SingleRotateWithLeft(TreeNode*& root)
{//左左型
	TreeNode* K2 = root;

	TreeNode* K1 = K2->left;
	K2->left = K1->right;
	K1->right = K2;
	//K1经过旋转后成为了新的根节点,K2是其右孩子

	K2->height = max(Height(K2->left), Height(K2->right)) + 1;
	K1->height = max(Height(K1->left), K2->height) + 1;

	root = K1;
}

void AVLTree::SingleRotateWithRight(TreeNode*& root)
{//右右型
	TreeNode* K1 = root;

	TreeNode* K2 = K1->right;
	K1->right = K2->left;
	K2->left = K1;
	//K1经过旋转后成为了新的根节点,K2是其左孩子

	K1->height = max(Height(K1->left), Height(K1->right)) + 1;
	K2->height = max(K1->height, Height(K2->right)) + 1;

	root = K2;
}

void AVLTree::DoubleRotateWithLeft(TreeNode*& root)
{//左右型
	TreeNode* K3 = root;
	//1. 先右旋
	SingleRotateWithRight(K3->left);
	//2. 后左旋
	SingleRotateWithLeft(K3);

	root = K3;
}

void AVLTree::DoubleRotateWithRight(TreeNode*& root)
{//右左型
	TreeNode* K3 = root;
	//1. 先左旋
	SingleRotateWithLeft(K3->right);
	//2. 再右旋
	SingleRotateWithRight(K3);

	root = K3;
}

void AVLTree::_insert(const Type& data, TreeNode*& root)
{if (root == nullptr)
	{root = new TreeNode{data };
		return;
	}
	if (data< root->data)
	{//左子树插入
		_insert(data, root->left);
		if (Height(root->left) - Height(root->right) == 2)
		{	if (data< root->left->data)
			{		SingleRotateWithLeft(root);	//单旋转:左左型
			}
			else
			{		DoubleRotateWithLeft(root);	//双旋转:左右型
			}
		}
	}
	else if (data >root->data)
	{//右子树插入
		_insert(data, root->right);
		if (Height(root->right) - Height(root->left) == 2)
		{	if (data >root->right->data)
			{		SingleRotateWithRight(root);	//单旋转:右右型
			}
			else
			{		DoubleRotateWithRight(root);	//双旋转:右左型
			}
		}
	}
	//否则树已经在节点中了,我们什么也不做

	//update树节点的高度
	root->height = max(Height(root->left), Height(root->right)) + 1;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


当前名称:AVL树(平衡二叉树)图解-创新互联
文章转载:http://scyanting.com/article/dsdoph.html