C++ 实现平衡二叉树(AVL树)(完整代码)

Posted Wecccccccc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 实现平衡二叉树(AVL树)(完整代码)相关的知识,希望对你有一定的参考价值。

#include <iostream>
using namespace std;
typedef int KeyType;

class AVLNode
{
	friend class AVLTree;
public:
	AVLNode() :lchild(nullptr), rchild(nullptr) {};
private:
	KeyType key;
	int bf;
	AVLNode *lchild;
	AVLNode *rchild;
};

class AVLTree
{
public:
	AVLTree() :root(nullptr) {};
	AVLNode *LL_Rotate(AVLNode *a);
	AVLNode *RR_Rotate(AVLNode *a);
	AVLNode *LR_Rotate(AVLNode *a);
	AVLNode *RL_Rotate(AVLNode *a);
	void CreateTree();
	void InOrderTree();
	void AVLInsert(AVLNode *&pavlt, AVLNode *s);
private:
	AVLNode *root;
	void InOrder(AVLNode *cur);
};

AVLNode *AVLTree::LL_Rotate(AVLNode *a)
{
	AVLNode *b;
	b = a->lchild;
	a->lchild = b->rchild;
	b->rchild = a;
	a->bf = b->bf = 0;
	return b;
}

AVLNode *AVLTree::RR_Rotate(AVLNode *a)
{
	AVLNode *b;
	b = a->rchild;
	a->rchild = b->lchild;
	b->lchild = a;
	a->bf = b->bf = 0;
	return b;
}

AVLNode *AVLTree::LR_Rotate(AVLNode *a)
{
	AVLNode *b, *c;
	b = a->lchild;
	c = b->rchild;
	a->lchild = c->rchild;
	b->rchild = c->lchild;
	c->lchild = b;
	c->rchild = a;
	if (c->bf == 1)
	{
		a->bf = -1;
		b->bf = 0;
	}
	else if (c->bf == -1)
	{
		a->bf = 0;
		b->bf = 1;
	}
	else
	{
		a->bf = b->bf = 0;
	}
	c->bf = 0;
	return c;
}


AVLNode *AVLTree::RL_Rotate(AVLNode *a)
{
	AVLNode *b, *c;
	b = a->rchild;
	c = b->lchild;
	a->rchild = c->lchild;
	b->lchild = c->rchild;
	c->lchild = a;
	c->rchild = b;
	if (c->bf == 1)
	{
		a->bf = 0;
		b->bf = -1;
	}
	else if (c->bf == -1)
	{
		a->bf = 1;
		b->bf = 0;
	}
	else
	{
		a->bf = b->bf = 0;
	}
	c->bf = 0;
	return c;
}


void AVLTree::AVLInsert(AVLNode *&pavlt, AVLNode *s)
{
	AVLNode *f, *a, *b, *p, *q;
	if (pavlt == nullptr)//没有根节点,那么插入的结点s就当作根结点
	{
		pavlt = s;
		return;
	}
	a = pavlt;//指针a记录离*s最近的平衡因子不为0的结点,f指向*a的父结点
	f = nullptr;
	p = pavlt;
	q = nullptr;
	while (p != nullptr)//寻找插入结点的位置及最小平衡子树
	{
		if (p->key == s->key) return;//AVL树中已存在该关键字
		if (p->bf != 0)//找最小不平衡子树
		{
			a = p;
			f = q;
		}
		q = p;
		if (s->key < p->key) p = p->lchild;
		else p = p->rchild;
	}
	if (s->key < q->key) q->lchild = s;//结点*s插入合适的位置
	else q->rchild = s;
	p = a;
	while (p != s)//插入结点后,修改相关结点的平衡因子
	{
		if (s->key < p->key)
		{
			p->bf++;
			p = p->lchild;
		}
		else
		{
			p->bf--;
			p = p->rchild;
		}
	}
	if (a->bf > -2 && a->bf < 2) return;//插入结点后,没有破坏树的平衡性
	if (a->bf == 2)
	{
		b = a->lchild;
		if (b->bf == 1) p = LL_Rotate(a);//结点插在*a的左孩子的左子树中
		else p = LR_Rotate(a);//结点插在*a的左孩子的右子树中
	}
	else {
		b = a->rchild;
		if (b->bf == 1) p = RL_Rotate(a);//结点插在*a的右孩子的左子树中
		else p = RR_Rotate(a);//结点插在*a的右孩子的右子树中
	}
	if (f == nullptr) pavlt = p;//原*a是AVL树的根
	else if (f->lchild == a) f->lchild = p;//将新子树连到原结点*a的双亲结点上
	else f->rchild = p;
}


void AVLTree::CreateTree()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		AVLNode *s = new AVLNode;
		cin >> s->key;
		AVLInsert(root, s);
	}
}


void AVLTree::InOrder(AVLNode *cur)
{
	if (cur)
	{
		InOrder(cur->lchild);
		cout << cur->key << " ";
		InOrder(cur->rchild);
	}
}

void AVLTree::InOrderTree()
{
	InOrder(root);
	cout << endl;
}

int main()
{
	AVLTree t;
	t.CreateTree();
	t.InOrderTree();
	return 0;
}

测试结果:
在这里插入图片描述

以上是关于C++ 实现平衡二叉树(AVL树)(完整代码)的主要内容,如果未能解决你的问题,请参考以下文章

STL源码笔记(18)—平衡二叉树AVL(C++封装+模板)

平衡二叉树 AVL树结构详解 [Java实现]--源码部分

你真的懂树吗?二叉树AVL平衡二叉树伸展树B-树和B+树原理和实现代码详解...

你真的懂树吗?二叉树AVL平衡二叉树伸展树B-树和B+树原理和实现代码详解...

你真的懂树吗?二叉树AVL平衡二叉树伸展树B-树和B+树原理和实现代码详解...

你真的懂树吗?二叉树AVL平衡二叉树伸展树B-树和B+树原理和实现代码详解...