伸展树部分实现(数据结构与算法分析——C 语言描述 第四章)

这本书在第四章给出了(自底向上)伸展树的描述,但没有给出对应的代码。    

其第十二章描述了自顶向下伸展树,且给出了代码。作为附带,描述了一些与第四章实现相关的细节,但由于其情况多样,实现起来仍旧相当困难。

这里给出其第四章伸展树的伸展和插入的实现,没有使用第十二章所描述的父链与栈。(不保证无错,希望读者能给出建议)

Splay.h

#ifndef _Splay_H

struct SplayNode;
typedef struct SplayNode *SplayTree;
typedef int ElementType;

SplayTree MakeEmpty( SplayTree T );
SplayTree Find( ElementType X, SplayTree T );
SplayTree FindMin( SplayTree T );
SplayTree FindMax( SplayTree T );
SplayTree Insert( ElementType X, SplayTree T );
SplayTree Remove( ElementType X, SplayTree T );
ElementType Retrieve( SplayTree T );

void PrintTree( SplayTree T );

#endif 

Splay.c

#include "Splay.h"
#include "Error.h"
#include <stdlib.h>
#include <stdio.h>

struct SplayNode
{
	ElementType Element;
	SplayTree	Left;
	SplayTree	Right;
};

typedef struct SplayNode *Position;
static Position Root = NULL;



static Position
SingleRotateWithLeft( Position K2 )
{
	Position K1;

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

	return K1;
}

static Position
SingleRotateWithRight( Position K1 )
{
	Position K2;

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

	return K2;
}

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 );
}

static SplayTree
SplayWithRoot( ElementType Item, Position T )
{
	if ( T != NULL && T->Element != Item )
	{
		if ( T->Left != NULL &&
				T->Left->Element == Item )
			//zig
			T = SingleRotateWithLeft( T );
		else
		if ( T->Right != NULL &&
				T->Right->Element == Item )
			//zag
			T = SingleRotateWithRight( T );
	}

	return T;
}


static SplayTree
SplayWithLeft( ElementType Item, Position T )
{
	if ( T != NULL && T->Left != NULL )
	{
		if ( T->Left->Right != NULL && 
				T->Left->Right->Element == Item )
			//zig-zag
			T = DoubleRotateWithLeft( T );
		else
		if ( T->Left->Left != NULL &&
				T->Left->Left->Element == Item )
		{
			//zig-zig
			T = SingleRotateWithLeft( T );
			T = SingleRotateWithLeft( T );
		}
	}

	return T;
}


static SplayTree
SplayWithRight( ElementType Item, Position T )
{
	if ( T != NULL && T->Right != NULL )
	{
		if ( T->Right->Left != NULL &&
				T->Right->Left->Element == Item )
			//zag-zig
			T = DoubleRotateWithRight( T );
		else
		if ( T->Right->Right != NULL &&
				T->Right->Right->Element == Item )
		{
			//zag-zag
			T = SingleRotateWithRight( T );
			T = SingleRotateWithRight( T );
		}
	}

	return T;
}

static SplayTree
insert( ElementType X, SplayTree T )
{
	if ( T == NULL )
	{
		T = malloc( sizeof( struct SplayNode ) );

		if ( T == NULL )
			FatalError( "Out of space!!!" );

		T->Element = X;
		T->Left = NULL;
		T->Right = NULL;
	}
	else
	if ( X < T->Element )
	{
		T->Left = insert( X, T->Left );
		T = SplayWithLeft( X, T );
	}
	else
	if ( X > T->Element )
	{
		T->Right = insert( X, T->Right );
		T = SplayWithRight( X, T );
	}

	if ( T == Root )
		return SplayWithRoot( X, T );
	return T;
}

SplayTree
Insert( ElementType X, SplayTree T )
{
	Root = T;
	return insert( X, T );
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值