PAT A 1066 Root of AVL Tree (25分) *AVL树的构造

一、AVL构造思路

1、定义

(1)平衡因子:结点的平衡因子为其左子树的高度减去右子树的高度。
(2)AVL树:AVL树是所有结点平衡因子绝对值不超过1的BST(二叉查找树)。

因此首先定义AVL树的数据结构:

struct node
{
	int data, h;
	node *lchild, *rchild;
};
node *root = NULL;
2、平衡

·平衡对象:最小失衡子树,也就是以自下而上第一个平衡因子绝对值大于一的结点为根的子树;
(1)在最小失衡结点,左子树的左子树插入导致失衡:对最小失衡子树做右旋;
右旋操作:
在这里插入图片描述

void R( node *&t )
{
	node *temp = t->lchild;
	t->lchild = temp->rchild;
	temp->rchild = t;
	update(t);
	t = temp;
}

(2) 在最小失衡结点,右子树的右子树插入导致失衡:对最小失衡子树做左旋;
左旋操作参考右旋。

void L( node *&t )
{
	node *temp = t->rchild;
	t->rchild = temp->lchild;
	temp->lchild = t;
	update(t);
	t = temp;
}

(3)在最小失衡结点,左子树的右子树插入导致失衡:对最小失衡子树左子树做左旋,再对最小失衡子树右旋;

(4)在最小失衡结点,右子树的左子树插入导致失衡:对最小失衡子树右子树做右旋,再对最小失衡子树左旋;
先右后左旋转操作:
在这里插入图片描述

完整的插入函数:

void insert( node *&t, int key )
{
	if( !t )
	{
		t = new node;
		t->data = key;
		t->lchild = t->rchild = NULL;
		t->h = 1;
	}
	else if( key < t->data )
	{
		insert( t->lchild, key );
		if( factor(t) == 2 && factor(t->lchild) == 1 )
			R(t);
		else if( factor(t) == 2 && factor(t->lchild) == -1 )
		{
			L(t->lchild);
			R(t);
		}
		update(t);
	}
	else
	{
		insert( t->rchild, key );
		if( factor(t) == -2 && factor(t->rchild) == -1 )
			L(t);
		else if( factor(t) == -2 && factor(t->rchild) == 1 )
		{
			R(t->rchild);
			L(t);
		}
		update(t);
	}
}

二、代码

#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
	int data, h;
	node *lchild, *rchild;
};
int get_h( node *t )
{
	return t ? t->h:0;
}
int factor( node *t )
{
	return get_h(t->lchild) - get_h(t->rchild);
}
void update( node *&t )
{
	t->h = max( get_h(t->lchild), get_h(t->rchild) ) + 1;
}
void R( node *&t )
{
	node *temp = t->lchild;
	t->lchild = temp->rchild;
	temp->rchild = t;
	update(t);
	t = temp;
}
void L( node *&t )
{
	node *temp = t->rchild;
	t->rchild = temp->lchild;
	temp->lchild = t;
	update(t);
	t = temp;
}
void insert( node *&t, int key )
{
	if( !t )
	{
		t = new node;
		t->data = key;
		t->lchild = t->rchild = NULL;
		t->h = 1;
	}
	else if( key < t->data )
	{
		insert( t->lchild, key );
		if( factor(t) == 2 && factor(t->lchild) == 1 )
			R(t);
		else if( factor(t) == 2 && factor(t->lchild) == -1 )
		{
			L(t->lchild);
			R(t);
		}
		update(t);
	}
	else
	{
		insert( t->rchild, key );
		if( factor(t) == -2 && factor(t->rchild) == -1 )
			L(t);
		else if( factor(t) == -2 && factor(t->rchild) == 1 )
		{
			R(t->rchild);
			L(t);
		}
		update(t);
	}
}
int main()
{
	int N;
	node *root = NULL;
	scanf("%d", &N);
	for( int i = 0, key; i < N; ++i )
	{
		scanf("%d", &key);
		insert(root, key);
	}
	printf("%d", root->data);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值