平衡二叉树(AVLTree)

         平衡二叉树(AVLTree)是指带平衡条件的二叉查找树。AVLTree要求每个节点的左子树和右子树的高度之差最多为1。当因为插入或删除操作导致AVLTree不满足该平衡条件时就需要进行调整操作,包括单旋转和双旋转操作。也正是因为需要时刻保持树的平衡条件,从而使得AVLTree的插入和删除操作较为复杂。

以下给出AVLTree的递归实现。


AVLTree.h:

#ifndef _AVLTree_H
#define _AVLTree_H

struct AvlNode;
typedef struct AvlNode* Position;
typedef struct AvlNode* AvlTree;
typedef int ElementType;
AvlTree MakeEmpty(AvlTree& T);
Position Find(ElementType X,AvlTree T );
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree& T);
AvlTree Delete(ElementType X,AvlTree T);
int GetHeight(Position P);//获取节点的高度
//前序遍历AVLTree
void PPrintTree(AvlTree T);
//中序遍历AVLTree
void MPrintTree(AvlTree T);
//后序遍历AVLTree
void LPrintTree(AvlTree T);

//辅助函数
//单旋转 返回新根节点(按失衡原因分为四种旋转)
Position SingleRotateWithLeft(Position K2);//左左
Position SingleRotateWithRight(Position K2);//右右
//双旋转  返回新的根节点
Position DoubleRotateWithLeft(Position k2);//左右
Position DoubleRotateWithRight(Position K2);//右左

int Max(int a,int b);
#endif 


AVLTree.cpp:

#include "AVLTree.h"
#include <stdio.h>
#include <stdlib.h>

int Max(int a,int b)
{
 if(a>b)
	 return a;
 else
	 return b;
}
struct AvlNode
{
 ElementType Element;
 AvlTree Left;
 AvlTree Right;
 int Heihgt;
};

AvlTree MakeEmpty(AvlTree& T)
{
 if(T!=NULL)
  {
	T->Left=NULL;
	T->Right=NULL;

   // MakeEmpty(T->Left);
	//MakeEmpty(T->Right);
	free(T);
	T=NULL;
  }
  return NULL;
}

int GetHeight(Position P)
{
 if(P==NULL)
  return -1;
 else
  return P->Heihgt; 

}

Position Find(ElementType X,AvlTree T)
{
 if(T==NULL)
   return NULL;
 else if(X<T->Element)
   return Find(X,T->Left);
 else if(X>T->Element)
   return Find(X,T->Right);
 else 
   return T; 
}

Position FindMin(AvlTree T)
{
 if(T==NULL)
	return NULL;
 else if(T->Left==NULL)
	return T;
 else 
    return FindMin(T->Left);
}

Position FindMax(AvlTree T)
{
 if(T==NULL)
	return NULL;
 else if(T->Right==NULL)
	return T;
 else
	return FindMax(T->Right);

}

AvlTree Insert(ElementType X,AvlTree& T)
{
 if(T==NULL)
	{
		T=(AvlTree)malloc(sizeof(struct AvlNode));
	  if(T==NULL)
		 printf("out of space \n");
	  else
	  {
      T->Element=X;
	  T->Heihgt=0;
	  T->Left=NULL;
	  T->Right=NULL;
	  }
	 
	}
 else if(X<T->Element)
	{
	 T->Left=Insert(X,T->Left);
	 if(GetHeight(T->Left)-GetHeight(T->Right)==2)//需要调整恢复平衡
		if(X<T->Left->Element)//左左
			T=SingleRotateWithLeft(T);
		else //左右
			T=DoubleRotateWithLeft(T);
	}
 else if(X>T->Element)
	{
	T->Right=Insert(X,T->Right);
	 if(GetHeight(T->Right)-GetHeight(T->Left)==2)//需要调整恢复平衡
		if(X>T->Right->Element)//右右
			T=SingleRotateWithRight(T);
		else //右左
			T=DoubleRotateWithRight(T);
	}
 
 T->Heihgt=Max(GetHeight(T->Left),GetHeight(T->Right))+1;

 return T;

}

//该删除函数 只做到了正确删除目标节点功能,但没有处理删除导致的树平衡被破坏的情况
AvlTree Delete(ElementType X,AvlTree T)//返回被删除位置新节点的指针
{
	Position TemCell;
	if(T==NULL)
		printf("Element is not find \n");
	else if(X<T->Element)
	{
		T->Left=Delete(X,T->Left);
	
	}
	else if(X>T->Element)
	{
		T->Right=Delete(X,T->Right);
	
	}
	else//找到目节点
	{
		if(T->Left && T->Right)//有两个儿节点
		{
			TemCell=FindMin(T->Right);
			T->Element=TemCell->Element;
			T->Right=Delete(TemCell->Element,T->Right);	 
		}
		else//注:最终被删除的节点为:单子节点或叶节点
		{
			TemCell=T;
			if(T->Left==NULL)
				{
					T=T->Right;
			    }
			else if(T->Right==NULL)
			   {
				T=T->Left;
			   }
			free(TemCell);
		}
	}
	return T;
}

//前序遍历AVLTree
void PPrintTree(AvlTree T)
{
	if(T==NULL)
		return;
	printf("%d ",T->Element);
	PPrintTree(T->Left);
	PPrintTree(T->Right);
}
//后序遍历AVLTree
void LPrintTree(AvlTree T)
{
 if(T!=NULL)
 {
	LPrintTree(T->Left);
	LPrintTree(T->Right);
	printf("%d ",T->Element);
 }
}
//中序遍历AVLTree
void MPrintTree(AvlTree T)
{
if(T!=NULL)
{
 MPrintTree(T->Left);
 printf("%d ",T->Element);
 MPrintTree(T->Right);
}
}

//单旋转 返回新根节点
Position SingleRotateWithLeft(Position K2)//左左
{
	Position K1;
	K1=K2->Left;
	K2->Left=K1->Right;
	K1->Right=K2;
	K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1;
	K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1;
	return K1;
}
Position SingleRotateWithRight(Position K2)//右右
{
	Position K1;
	K1=K2->Right;
	K2->Right=K1->Left;
	K1->Left=K2;
	K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1;
	K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1;
	return K1;

}
//双旋转  返回新的根节点
Position DoubleRotateWithLeft(Position K2)//左右
{
	K2->Left=SingleRotateWithRight(K2->Left);
	return SingleRotateWithLeft(K2);
}
Position DoubleRotateWithRight(Position K2)//右左
{
	K2->Right=SingleRotateWithLeft(K2->Right);
	return SingleRotateWithRight(K2);
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值