AVL树 插入

AVL树

一颗AVL树或者空树,它具有二叉搜索树的性质,它的左子树和右子树都是AVL树,且左子树和右子树的高度只差绝对值不超过1
当插入一个值后,左右子树高度差之不小于1,那么就要做平衡处理。
有一个左平衡,一个右平衡,一个左旋转,一个右旋转,当插入后balance的绝对值大于一时,就需要就需要旋转,并且重新改变balance的值,
1.如果插入的数据在一条直线上,就只旋转一次,是在左边就进行左旋转,在右边,就进行右旋转,旋转后把第二个节点提上去,父子节点分别挂在两边。之后再分别把balance改变
2.如果插入的是一条折线,就需要进行两次旋转,一次右旋转,再一次左旋转,如下图。

在这里插入图片描述

#include<stddef.h>
#include<stdio.h>
#include<iostream>
#include<assert.h>
using namespace std;

typedef int KeyType;
typedef struct AVLNode
{
	KeyType key;
	struct AVLNode* leftchild;
	struct AVLNode* parent;
	struct AVLNode* rightchild;
	int balance;
}AVLNode,*AVLTree;


AVLNode* Buynode(KeyType kx)
{
	AVLNode* s = (AVLNode*)malloc(sizeof(AVLNode));
	if (s == nullptr)exit(1);
	memset(s, 0, sizeof(AVLNode));

	s->key = kx;
	s->balance = 0;
	return s;
}
AVLNode* MakeRoot(KeyType kx)
{
	AVLNode* root = Buynode(kx);
	return root;
}
void RotateLeft(AVLTree& tree, AVLNode* ptr)
{
	AVLNode* newroot = ptr->rightchild;

	newroot->parent = ptr->parent;

	ptr->rightchild = newroot->leftchild;
	if (newroot->leftchild != nullptr)
	{
		newroot->leftchild->parent = ptr;
	}
	newroot->leftchild = ptr;
	if (ptr == tree)
	{
		tree = newroot;
	}
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	
	ptr->parent = newroot;
}

void RotateRight(AVLTree& tree, AVLNode* ptr)
{
	AVLNode* newroot = ptr->leftchild;

	newroot->parent = ptr->parent;

	ptr->leftchild = newroot->rightchild;

	if (newroot->rightchild != nullptr)
	{
		newroot->rightchild->parent = ptr;
	}
	newroot->rightchild = ptr;
	if (ptr == tree)
	{
		tree = newroot;
	}
	else
	{
		if (ptr->parent->leftchild == ptr)
		{
			ptr->parent->leftchild = newroot;
		}
		else
		{
			ptr->parent->rightchild = newroot;
		}
	}
	ptr->parent = newroot;
}
void RightBalance(AVLTree& tree, AVLNode* ptr)
{
	AVLNode* rightsub = ptr->rightchild, * leftsub = nullptr;
	switch (rightsub->balance)
	{
	case 0:cout << "right balance" << endl;break;
	case 1:
		ptr->balance = 0;
		rightsub->balance = 0;
		RotateLeft(tree, ptr);
		break;
	case -1:
		leftsub = rightsub->leftchild;
		switch (leftsub->balance)
		{
		case 0:
			ptr->balance = 0;
			rightsub->balance = 0;
			break;
		case 1:
			ptr->balance = -1;
			rightsub->balance = 0;
			break;
		case -1:
			ptr->balance = 0;
			rightsub->balance = 1;
			break;
		}
		leftsub->balance = 0;
		RotateRight(tree, rightsub);
		RotateLeft(tree, ptr);
		break;
	}
}
void LeftBalance(AVLTree& tree, AVLNode* ptr)
{
	AVLNode* leftsub = ptr->leftchild, * rightsub = nullptr;
	switch (leftsub->balance)
	{
	case 0: cout << "left balance " << endl; break;
	case -1:
		ptr->balance = 0;
		leftsub->balance = 0;
		RotateRight(tree, ptr);
		break;
	case 1:
		rightsub = leftsub->rightchild;
		switch (rightsub->balance)
		{
		case -1:
			leftsub->balance = 0;
			ptr->balance = 1;
			break;
		case 1:
			leftsub->balance = -1;
			ptr->balance = 0;
			break;
		case 0:
			leftsub->balance = 0;
			ptr->balance = 0;
			break;
		}
		rightsub->balance = 0;
		RotateLeft(tree, leftsub);
		RotateRight(tree, ptr);
		break;
	}
}

void PassBalance(AVLTree& tree, AVLNode* p)
{
	AVLNode* pa = p->parent;
	bool tall = true;
	for (; pa != nullptr && tall;)
	{
		if (pa->leftchild == p)
		{
			switch (pa->balance)
			{
			case 0: pa->balance = -1; break;
			case 1: pa->balance = 0;
				tall = false;
				break;
			case -1:
				LeftBalance(tree, pa);
				tall = false;
				break;
			}
		}
		else  // p -->pa->rightchild
		{
			switch (pa->balance)
			{
			case 0: pa->balance = 1; break;
			case -1: pa->balance = 0;
				tall = false;
				break;
			case 1:
				RightBalance(tree, pa);
				tall = false;
				break;
			}
		}
		p = pa;
		pa = p->parent;
	}
}
bool Insert(AVLTree& tree, KeyType kx)
{
	if (tree == nullptr)
	{
		tree = MakeRoot(kx);
		return true;
	}
	AVLNode* pa = nullptr;
	AVLNode* p = tree;
	while (p != nullptr && p->key != kx)
	{
		pa = p;
		p = kx < p->key ? p->leftchild : p->rightchild;
	}
	if ( p != nullptr&& p->key == kx)return false;
	p = Buynode(kx);
	p->parent = pa;
	if (kx < pa->key)
	{
		pa->leftchild = p;
	}
	else
	{
		pa->rightchild = p;
	}
	PassBalance(tree, p);
	return true;
}



void InOrder(AVLNode* ptr)
{
	if (ptr != NULL)
	{
		InOrder(ptr->leftchild);
		cout << ptr->key << " " << ptr->balance << endl;
		InOrder(ptr->rightchild);
	}
}
int main()
{
	int ar[] = { 16,3,7,11,9,26,18,14,15 };

	AVLTree root = nullptr;
	for (auto& x : ar)
	{
		cout << Insert(root, x) << endl;
	}
	InOrder(root);

	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值