AVL树的实现

1.简述

AVL树本质是二叉查找树,与二叉查找树不同的是AVL树带有平衡条件
平衡条件: 每个节点的左子树和右子树的高度最多相差1,空树的高度为-1
插入分以下四种情况:

  • 1 对a的左子树的左子树进行一次插入
  • 2 对a的左子树的右子树进行一次插入
  • 3 对a的右子树的左子树进行一次插入
  • 4 对a的右子树的右子树进行一次插入
    (1/4情况为单旋;2/3情况为双旋转)
    在这里插入图片描述

2.声明

#ifndef _AVL_H_
#define _AVL_H_

class AvlNode;
typedef AvlNode* Position;
typedef AvlNode* AvlTree;

class AvlNode {
public:
	int element;
	AvlTree left;
	AvlTree right;
	int height;		//记录树的高度
};

int Height(Position p);
AvlTree MakeEmpty(AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
Position Find(int element, AvlTree T);
AvlTree Insert(int element, AvlTree T);

Position SingleRotateWithLeft(Position k2);
Position SingleRotateWithRight(Position k2);
Position DoubleRoateWithLeft(Position k3);
Position DoubleRoateWithRight(Position k3);
#endif // !_AVL_H_

3.实现

#include<iostream>
#include"avl.h"
#include<algorithm>
using namespace std;

int Height(Position p)
{
	if (p == NULL)
		return -1;
	else
		return p->height;
}

AvlTree MakeEmpty(AvlTree T)
{
	if (T != NULL)
	{
		MakeEmpty(T->left);
		MakeEmpty(T->right);
		delete T;
		T = NULL;
	}
	return NULL;
}

Position Find(int element, AvlTree T)
{
	if (T == NULL)
		return NULL;
	if (element<T->element)
		return Find(element, T->left);
	else
	{
		if (element>T->element)
			return Find(element, T->right);
		else
			return T;
	}

}

//一直往左孩子走
Position FindMin(AvlTree T)
{
	if (T != NULL)
	{
		while (T->left != NULL)
			T = T->left;
	}
	return T;
}

Position FindMax(AvlTree T)
{
	if (T != NULL)
	{
		while (T->right != NULL)
			T = T->right;
	}
	return T;
}

/**
* 单旋
*/
Position SingleRotateWithLeft(Position k2)
{
	Position k1;
	k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	k2->height = max({ Height(k2->left),Height(k2->right)})+1;
	k1->height = max({Height(k1->left),k2->height})+1;
	return k1;
}

Position SingleRotateWithRight(Position k2)
{
	Position k1;
	k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;
	k2->height = max({ Height(k2->left),Height(k2->right) }) + 1;
	k1->height = max({ Height(k1->right),k2->height }) + 1;
	return k1;
}

/**
* 双旋
*/

/**
* 先进行一次单右旋,再进行一次单左旋
*/
Position DoubleRoateWithLeft(Position k3)
{
	k3->left = SingleRotateWithRight(k3->left);
	return SingleRotateWithLeft(k3);
}

Position DoubleRoateWithRight(Position k3)
{
	k3->right = SingleRotateWithLeft(k3->right);
	return SingleRotateWithRight(k3);
}

AvlTree Insert(int element, AvlTree T)
{
	if (T == NULL)
	{
		T = new AvlNode();
		T->element = element;
		T->height = 0;
		T->right = T->left = NULL;
	}
	else
	{
		if (element < T->element)
		{
			T->left = Insert(element, T->left);
			if (Height(T->left) - Height(T->right) == 2)
			{
				if (element < T->left->element)
					SingleRotateWithLeft(T);
				else
					DoubleRoateWithLeft(T);
			}
		}
		else
			if (element>T->element)
			{
				T->right = Insert(element, T->right);
				if (Height(T->right) - Height(T->left) == 2)
				{
					if (element > T->right->element)
						T = SingleRotateWithRight(T);
					else
						T = DoubleRoateWithRight(T);
				}
			}
	}
	//element 已经存在
	T->height = max({ Height(T->left),Height(T->right) }) + 1;
	return T;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值