数据结构之平衡二叉搜索树

本文详细介绍了AVL树,一种自平衡二叉搜索树,通过维持节点高度差限制在1,通过旋转操作保证插入和删除后树的平衡。文章涵盖了AVL树的原理、旋转类型以及C++实现的关键代码段。
摘要由CSDN通过智能技术生成

什么是平衡二叉树

AVL是一种自平衡二叉搜索树(self-balancing binary search tree)的数据结构,它的名称来源于其发明者G.M. Adelson-Velsky和E.M. Landis。AVL树通过在每次插入或删除节点时进行旋转操作,来确保树的高度始终保持在一个较小的范围内,从而保持树的平衡性。

AVL树的平衡性是通过节点的高度差(即左子树高度和右子树高度之差)来衡量的。在一个平衡的AVL树中,任何节点的左子树和右子树的高度差不超过1。当插入或删除节点导致某个节点的平衡被打破时,AVL树会通过旋转操作来恢复平衡。AVL树的旋转操作分为四种类型:左旋、右旋、左右旋和右左旋。左旋和右旋用于处理节点的子树高度差为2的情况,而左右旋和右左旋用于处理节点的子树高度差为-2的情况。通过这些旋转操作,AVL树可以在插入或删除节点时保持平衡,并且可以在O(log n)的时间复杂度内进行插入、删除和查找操作。AVL树在许多应用中都有广泛的应用,特别是在需要高效的插入、删除和查找操作的场景中。它是一种重要的数据结构,被用于数据库、编译器、操作系统等领域。

旋转操作

 

 

 

 

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#define HEIGHT(p) ((p==NULL)?-1:(p->height))
#define MAX(a,b) ((a)>(b)?(a):(b))

typedef struct 
{
	int key;
	char value[20];
}Data;

typedef struct AVLTreeNode 
{
	Data data;
	int height;
	struct AVLTreeNode* LChild;
	struct AVLTreeNode* RChild;
}Node;
//创建节点
Node* create_node(Data data) 
{
	Node* newNode = (Node*)malloc(sizeof(Node));
	assert(newNode);
	newNode->data = data;
	newNode->height = 0;
	newNode->LChild = NULL;
	newNode->RChild = NULL;
	return newNode;
}
//层次遍历
void print_tree(Node* tree)
{
	if (tree == NULL)
		return;
	Node* pmove = tree;
	Node* queue[1024];
	int front = 0;
	int tail = 0;
	queue[tail++] = pmove;
	printf("%d:%s\n", pmove->data.key, pmove->data.value);
	while (front != tail)
	{
		pmove = queue[front++];
		if (pmove->LChild != NULL)
		{
			queue[tail++] = pmove->LChild;
			printf("%d:%s\n", pmove->LChild->data.key, pmove->LChild->data.value);
		}
		else
		{
			printf("NULL\n");
		}
		if (pmove->RChild != NULL)
		{
			queue[tail++] = pmove->RChild;
			printf("%d:%s\n", pmove->RChild->data.key, pmove->RChild->data.value);
		}
		else 
		{
			printf("NULL\n");
		}
	
	}
}
//LL
Node* ll_rotation(Node* k2) 
{
	//旋转
	Node* k1 = k2->LChild;
	k2->LChild = k1->RChild;
	k1->RChild = k2;
	//节点高度
	k2->height = MAX(HEIGHT(k2->LChild), HEIGHT(k2->RChild)) + 1;
	k1->height = MAX(HEIGHT(k1->LChild), k2->height) + 1;
	return k1;
}
//RR
Node* rr_rotation(Node* k1) 
{
	Node* k2 = k1->RChild;
	k1->RChild = k2->LChild;
	k2->LChild = k1;
	k1->height = MAX(HEIGHT(k1->LChild), HEIGHT(k1->RChild)) + 1;
	k2->height = MAX(HEIGHT(k2->LChild), k1->height) + 1;
	return k2;
}
//LR
Node* lr_rotation(Node* k3) 
{
	k3->LChild = rr_rotation(k3->LChild);
	return ll_rotation(k3);

}
//RL
Node* rl_rotation(Node* k3) 
{
	k3->RChild = ll_rotation(k3->RChild);
	return rr_rotation(k3);
}

Node* insert_avl(Node* tree, Data data) 
{
	if (tree == NULL)
		tree = create_node(data);
	else if (data.key < tree->data.key) 
	{
		tree->LChild = insert_avl(tree->LChild, data);
		if (HEIGHT(tree->LChild) - HEIGHT(tree->RChild) == 2) 
		{
			if (data.key < tree->LChild->data.key) 
			{
				tree = ll_rotation(tree);
			}
			else 
			{
				tree = lr_rotation(tree);
			}

		}
	}
	else if (data.key > tree->data.key) 
	{
		tree->RChild = insert_avl(tree->RChild, data);
		if (HEIGHT(tree->RChild) - HEIGHT(tree->LChild) == 2) 
		{
			if (data.key > tree->RChild->data.key) 
			{
				tree = rr_rotation(tree);
			}
			else 
			{
				tree = rl_rotation(tree);
			}
		}
	}
	else 
	{
		printf("插入失败!关键字唯一!\n");
	}
	tree->height = MAX(HEIGHT(tree->LChild), HEIGHT(tree->RChild)) + 1;
	return tree;
}
Node* max_node(Node* tree) 
{
	if (tree == NULL)
		return NULL;
	while (tree->RChild != NULL) 
	{
		tree = tree->RChild;
	}
	return tree;
}
Node* min_node(Node* tree)
{
	if (tree == NULL)
		return NULL;
	while (tree->LChild != NULL) 
	{
		tree = tree->LChild;
	}
	return tree;
}
Node* erase_avl(Node* tree, int key)
{
	if (tree == NULL)
		return NULL;
	if (key < tree->data.key)
	{
		tree->LChild = erase_avl(tree->LChild, key);
		if (HEIGHT(tree->RChild) - HEIGHT(tree->LChild) == 2)
		{
			Node* rightNode = tree->RChild;
			if (rightNode != NULL && HEIGHT(rightNode->LChild) > HEIGHT(rightNode->RChild))
			{
				tree = rl_rotation(tree);
			}
			else
			{
				tree = rr_rotation(tree);
			}
		}
	}
	else if (key > tree->data.key)
	{
		tree->RChild = erase_avl(tree->RChild, key);
		if (HEIGHT(tree->LChild) - HEIGHT(tree->RChild) == 2)
		{
			Node* leftNode = tree->LChild;
			if (leftNode != NULL && HEIGHT(leftNode->RChild) > HEIGHT(leftNode->LChild))
			{
				tree = lr_rotation(tree);
			}
			else
			{
				tree = ll_rotation(tree);
			}
		}
	}
	else
	{
		if (tree->LChild != NULL && tree->RChild != NULL) 
		{
			if (HEIGHT(tree->LChild) > HEIGHT(tree->RChild)) 
			{
				Node* max = max_node(tree->LChild);
				tree->data = max->data;
				tree->LChild = erase_avl(tree->LChild, max->data.key);
			}
			else 
			{
				Node* min = min_node(tree->RChild);
				tree->data = min->data;
				tree->RChild = erase_avl(tree->RChild, min->data.key);
			}

		}
		else 
		{
			Node* temp = tree;
			tree = tree->LChild ? tree->LChild : tree->RChild;
			free(temp);
		}
	}
	return tree;
}


void test_avl()
{
	Data data[10] = { 0,"小美",1,"小芳",2,"小丽",3,"小小",4,"悠悠",5,"小妹",6,"小梅",7,"小爱",8,"笑笑",9,"筱花" };
	Node* root = NULL;
	for (int i = 0; i < 10; i++) 
	{
		root = insert_avl(root, data[i]);
	}
	print_tree(root);
	printf("----------------------\n");
	root=erase_avl(root, 7);
	print_tree(root);
}
int main() 
{
	test_avl();
	return 0;
}

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值