数据结构与算法分析之--->AvlTree的实现

主体风格参照Weiss于《数据结构与算法分析(C语言描述)》中的AvlTree的相关描述


自己补全了AvlTree的删除等操作以及课后习题的高效率双旋转


/* Project: AvlTree						*/
/* Author: ZZ_InoRi/Elasped_Hiyoti				*/
/* Home: http://blog.csdn.net/Elapsed_Hiyori		        */
/* IDE: VS2012							*/
/* Date: 2012/11/27	-> 19:53				*/
/* ============================================================ */

#define _AvlTree_H

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#ifdef  _AvlTree_H

struct	AvlNode;
typedef	struct AvlNode *Position;
typedef	struct AvlNode *AvlTree;

AvlTree		MakeEmpty( AvlTree T );
Position	FindMax( AvlTree T );
Position	FindMin( AvlTree T );
Position	Find( AvlTree T );
AvlTree		Insert( int X, AvlTree T );
AvlTree		Delete( int X, AvlTree T );
int			Retrueve( Position P );

#endif  /* _AvlTree_H */


struct AvlNode{

	int		Element;
	AvlTree	Left;
	AvlTree	Right;
	int		Height;

};


int Retrieve( Position P ){

    return P -> Element;
}


void PrintElement( int X ){

	printf("%d\t",X);
}


void PrintTree( AvlTree T ){

	if( T != NULL ){

		PrintTree( T -> Left );
		PrintElement( T -> Element );
		PrintTree( T -> Right );
	}
}


static int Height( Position P ){

	if( P == NULL )
		return -1;
	else
		return P -> Height;

}

static int Max( int a, int b ){

	return a > b ? a : b;

}

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 )
        while( T->Right != NULL )
			T = T->Right;

    return T;
}


static Position SingleRotateWithLeft( Position K2 ){

	Position K1;

	K1 = K2 -> Left;
	K2 -> Left = K1 -> Right;
	K1 -> Right = K2;

	K2 -> Height = Max( Height( K2 -> Left ), Height( K2 -> Right ) ) + 1;
	K1 -> Height = Max( Height( K1 -> Left ), Height( K1 -> Right ) ) + 1;

	return K1; // New Root

}


static Position SingleRotateWithRight( Position K1 ){

	Position K2;

	K2 = K1 -> Right;
	K1 -> Right = K2 -> Left;
	K2 -> Left = K1;

	K2 -> Height = Max( Height( K2 -> Left ), Height( K2 -> Right ) ) + 1;
	K1 -> Height = Max( Height( K1 -> Left ), Height( K1 -> Right ) ) + 1;

	return K2; // New Root

}


static Position DoubleRotateWithLeft( Position K3 ){

	K3 -> Left = SingleRotateWithRight( K3 -> Left );

	return SingleRotateWithLeft( K3 );

}


static Position DoubleRotateWithRight( Position K3 ){

	K3 -> Right = SingleRotateWithLeft( K3 -> Right );

	return SingleRotateWithRight( K3 );

}

	

AvlTree Insert( int X, AvlTree T ){

	if( T == NULL ){

		T = ( AvlTree )malloc( sizeof( struct AvlNode ) );
		if( T == NULL )
			return 0;
		else{

			T -> Element = X;
			T -> Height = 0;
			T -> Left = T -> Right = NULL;
		}
	}

	else if( X < T -> Element ){

		T -> Right = Insert( X, T -> Right );
		if( Height( T -> Left ) - Height( 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( Height( T -> Right ) - Height( T -> Left ) == 2 ){

			if( X > T -> Right -> Element )
				T = SingleRotateWithRight( T );
			else
				T = DoubleRotateWithRight( T );

		}

	}

			T -> Height = Max( Height( T -> Left ), Height( T -> Right ) ) + 1;

			return T; 

}


/*  以下为高效率的双旋转  */


Position H_DoubleRotateWithLeft( Position K3 )
{
	Position K1, K2;
	K1 = K3->Left;
	K2 = K1->Right;
	K1->Right = K2->Left;
	K3->Left = K2->Right;
	K2->Left = K1;
	K2->Right = K3;
	K1->Height = Max( Height(K1->Left), Height(K1->Right) ) + 1;
	K3->Height = Max( Height(K3->Left), Height(K3->Right) ) + 1;
	K2->Height = Max( K1->Height, K3->Height ) + 1;
	return K3;
}

/*  其实该效率略高的双旋转即手动双旋转,虽然效率略高,但是不直观  */



/*  假设要删除的结点是T:																				*/
/*  1. 如果T为叶结点,直接删除,然后一直向上调整到根结点;												*/
/*  2. 如果T有左子树L,找到L的最右结点X(就是<T的结点中最大的),用X的值替换掉T的值,问题变为删除X结点;  */
/*  3. 如果T有右子树R,找到R的最右结点X(就是>T的结点中最小的),用X的值替换掉T的值,问题变为删除X结点;  */


AvlTree Delete( int X, AvlTree T){

	Position TempCell;

	if( T == NULL ){

		printf("Element Not Found\n");
		return NULL;
	}

	else if( X > T -> Element ){

		T -> Right = Delete( X, T -> Right );
		if( Height( T -> Left ) - Height( T -> Right ) == 2 ){

			if( Height( T -> Left -> Left ) > Height( T -> Left -> Right ) ){
				// LL
				SingleRotateWithLeft( T );
			}
			else {
				// LR
				DoubleRotateWithLeft( T );
			}
		}
	}

	else if( X < T -> Element ){

		T -> Left = Delete( X, T -> Left );
		if( Height( T -> Right ) - Height( T -> Left ) == 2 ){

			if( Height( T -> Right -> Right ) > Height( T -> Right -> Left ) ){
				// RR
				SingleRotateWithRight( T );
			}
			else {
				// RL
				DoubleRotateWithRight( T );
			}
		}
	}

	else if( X == T -> Element ){
		// Find it
		if( T -> Right && T -> Left ){
			// Two Children
			TempCell = FindMin( T -> Right );
			T -> Element = TempCell -> Element;
			TempCell -> Element = X;
			Delete( X, T -> Right );

		}
		else {
			// One or Zero Child
			TempCell = T;
			if( T -> Right || T -> Left ){
				
				if( T -> Right == NULL )
					T = T -> Left;
				if( T -> Left == NULL )
					T = T -> Right;

				free( TempCell );
			}

			else {

				free( T );
				T = NULL;
			}
		}
	}

	return T;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值