平衡二叉树(AVL树)C语言实现

#include "stdio.h"    
#include "stdlib.h"   

#include "math.h"  
#include "time.h"


typedef  struct Node	/* 结点结构 */
{
	int data;	/* 结点数据 */
	int balance; /*  结点的平衡因子 */
	struct Node* lchild, * rchild;	/* 左右孩子指针 */
} Node, *Tree;

int r_rotate(Tree* T)
{
	Tree B;
	B = (*T)->lchild;
	(*T)->lchild = B->rchild;
	B->rchild = (*T);
	*T = B;
}

int l_rotate(Tree* T)
{
	Tree B;
	B = (*T)->rchild;
	(*T)->rchild = B->lchild;
	B->lchild = (*T);
	*T = B;
}

int keep_balance(Tree* T)  //此时T数不平衡,且左树高于右树,balance为2
{
	if ((*T)->balance > 0)     //左子树高,此时为LL或LR型   故先提取左子树
	{
		Tree L, B;
		L = (*T)->lchild;
		if (L->balance == 1)        //左树balance 与 根节点balance 同号 ,为LL型,直接右旋,全置零
		{
			(*T)->balance = 0;
			L->balance = 0;
			r_rotate(T);

		}
		else if (L->balance == -1)    //左树balance 与 根节点balance 异号 为LR型,平衡之后的平衡值取决于左子树的右子树的平衡值(自己画图看一下)
		{
			B = L->rchild;          
			if (B->balance = 1)
			{
				L->balance = 0;
				(*T)->balance = -1;
			}
			else if (B->balance == 0)
			{
				L->balance = 0;
				(*T)->balance = 0;
			}
			else
			{
				L->balance = 1;
				(*T)->balance = 0;
			}
			B->balance = 0;                
			l_rotate(&(*T)->lchild);       //先将左子树左旋,转换为LL再右旋
			r_rotate(T);
		}
	}
	else if ((*T)->balance < 0 )     //右子树高,此时为RR或RL型   故先提取右子树
	{
		Tree R, B1;
		R = (*T)->rchild;
		if (R->balance == -1)        //左树balance 与 根节点balance 同号 ,为RR型,直接右旋,全置零
		{
			(*T)->balance = 0;
			R->balance = 0;
			l_rotate(T);

		}
		else if (R->balance == 1)   
		{
			B1 = R->lchild;
			if (B1->balance = -1)
			{
				R->balance = 0;
				(*T)->balance = -1;
			}
			else if (B1->balance == 0)
			{
				R->balance = 0;
				(*T)->balance = 0;
			}
			else
			{
				R->balance = 1;
				(*T)->balance = 0;
			}
			B1->balance = 0;
			r_rotate(&(*T)->lchild);       
			l_rotate(T);
		}
	}
	return 1;

 }


int insertAVL(Tree* T, int value)
{
	if (!(*T))
	{
		*T = (Tree)malloc(sizeof(Node));
		(*T)->data = value;
		(*T)->lchild = NULL;
		(*T)->rchild = NULL;
		(*T)->balance = 0;
	}
	else
	{
		if ((*T)->data > value)
		{
			insertAVL(&(*T)->lchild, value);
			if ((*T)->balance = 1) //此时的T是插入部分的父母节点,根据其原本的balance判断其是否失去平衡
			{
				keep_balance(T);
			}
			else if((*T)->balance = 0)
			{
				(*T)->balance = 1;
			}
			else
			{
				(*T)->balance = 0;
			}

		}
		else if((*T)->data == value)
		{
			return 0;
		}
		else
		{
			insertAVL(&(*T)->rchild, value);
			if ((*T)->balance = -1)  
			{
				keep_balance(T);
			}
			else if ((*T)->balance = 0)
			{
				(*T)->balance = -1;
			}
			else
			{
				(*T)->balance = 0;
			}
		}
	}
	return 1;
}


int in_see(Tree T)
{
	if (!T)
	{
		return 0;
	}
	in_see(T->lchild);
	printf("%d ", T->data);
	in_see(T->rchild);
	return 1;
}


int main()
{
	int i;
	int a[10] = { 3,2,1,4,5,6,7,10,9,8 };
	Tree T = NULL;
	for (i = 0;i < 10;i++)
	{
		insertAVL(&T, a[i]);
	}
	insertAVL(&T, 0);
	in_see(T);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值