数据结构---平衡树

本文用C语言实现平衡书,平衡树相对一般的二叉查找树而言效率稍高,以下是源代码:


#include "AvlTree.h"
#include "malloc.h"


AvlTree CreatAvlTree(void)
{
	return NULL;
}

AvlTree MakeEmpty(AvlTree T)
{
	if (T != NULL)
	{
		MakeEmpty(T->Left);
		MakeEmpty(T->Right);
		free(T);
	}
	return NULL;
}

Position Find(AvlTree T, ElementType X)
{
	if (T == NULL)
	{
		printf("Element X is not in the search_tree!\r\n");
		return NULL;
	}
	if (X < T->Element)
	{
		return Find(T->Left, X);
	}
	else if (X>T->Element)
	{
		return Find(T->Right, X);
	}
	else
	{
		return T;
	}
}
Position FindMax(AvlTree T)
{
	while (T->Right != NULL)
	{
		T = T->Right;
	}
	return T;
}

Position FindMin(AvlTree T)
{
	while (T->Left != NULL)
	{
		T = T->Left;
	}
	return T;
}

int32_t Height(AvlTree T)
{
	if (T == NULL)
	{
		return -1;
	}
	else
	{
		return T->Height;
	}
}

/*返回二者中较大的*/
static int32_t Max(int32_t a, int32_t b)
{
	return a > b ? a : b;
}

/*修复情况一:对某节点的左儿子的左子树进行一次插入*/
static Position SingleRotaWithLeft(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), K2->Height) + 1;
	return K1;
}

/*修复情况四:对某节点的右儿子的右子树进行一次插入*/
static Position SingleRotaWithRight(Position K1)
{
	Position K2;
	K2 = K1->Right;
	K1->Right = K2->Left;
	K2->Left = K1;

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

/*修复情况二:对某节点的左儿子的右子树进行一次插入*/
static Position DoubleRotaWithLeft(Position K3)
{
	K3->Left = SingleRotaWithRight(K3->Left);
	return SingleRotaWithLeft(K3);
}

/*修复情况三:对某节点的右儿子的左子树进行一次插入*/
static Position DoubleRotaWithRight(Position K1)
{
	K1->Right = SingleRotaWithLeft(K1->Right);
	return SingleRotaWithRight(K1);
}

AvlTree Insert(AvlTree T, ElementType X)
{
	if (T == NULL)
	{
		T = (Position)malloc(sizeof(AvlTreeNode));
		if (T == NULL)
		{
			printf("Out of space!!!\r\n");
		}
		else
		{
			T->Element = X;
			T->Height = 0;
			T->Left = T->Right = NULL;
		}
	}
	else if (X < T->Element)
	{
		T->Left = Insert(T->Left, X);
		if (2 == (Height(T->Left) - Height(T->Right)))
		{
			if (X < T->Left->Element)
				T = SingleRotaWithLeft(T);
			else
				T = DoubleRotaWithLeft(T);
		}
	}
	else if (X > T->Element)
	{
		T->Right = Insert(T->Right, X);
		if (2 == (Height(T->Right) - Height(T->Left)))
		{
			if (X > T->Right->Element)
				T = SingleRotaWithRight(T);
			else
				T = DoubleRotaWithRight(T);
		}
	}

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


void PrintAllNodeRising(AvlTree T)
{
	if (T == NULL)
	{
		return;
	}
	PrintAllNodeRising(T->Left);
	printf("%d\r\n", T->Element);
	PrintAllNodeRising(T->Right);
}
void PrintAllNodeFalling(AvlTree T)
{
	if (T == NULL)
	{
		return;
	}
	PrintAllNodeFalling(T->Right);
	printf("%d\r\n", T->Element);
	PrintAllNodeFalling(T->Left);
}

static void PrintNodeName(AvlTree T, uint32_t Depth)
{
	for (uint16_t i = 0; i < Depth; i++)
	{
		putchar(' '); 
	}
	printf("*%d*--%d\r\n", Depth, T->Element);
}

static void PrintNode(AvlTree T, uint32_t Depth)
{
	if (T != NULL)
	{
		PrintNodeName(T, Depth);
		PrintNode(T->Left, Depth + 1);
		PrintNode(T->Right, Depth + 1);
	}
}
void PrintAllNode(AvlTree T)
{
	PrintNode(T, 0);
}


#ifndef __AVLTREE_H_
#define __AVLTREE_H_

#include "stdint.h"
#include <stdio.h>
#include <stdbool.h>

typedef int64_t ElementType;

typedef struct node
{
	ElementType Element;
	struct node *Left;
	struct node *Right;
	int32_t Height;
} AvlTreeNode;

typedef AvlTreeNode *PtrToNode;
typedef PtrToNode AvlTree;
typedef PtrToNode Position;

AvlTree CreatAvlTree(void);
AvlTree MakeEmpty(AvlTree T);
Position Find(AvlTree T, ElementType X);
Position FindMax(AvlTree T);
Position FindMin(AvlTree T);
int32_t Height(AvlTree T);
AvlTree Insert(AvlTree T, ElementType X);
AvlTree Delete(AvlTree T, ElementType X);
ElementType Retrieve(Position P);
void PrintAllNodeRising(AvlTree T);
void PrintAllNodeFalling(AvlTree T);
void PrintAllNode(AvlTree T);


#endif



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值