AVL树的实现

119 阅读2分钟

AVL树的实现

1、头文件

(AVL树.h)

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct AvlNode* makeEmpty(struct AvlNode* t);
struct AvlNode* find(int x, struct AvlNode* t);
struct AvlNode* findMin(struct AvlNode* t);
struct AvlNode* findMax(struct AvlNode* t);
struct AvlNode* insert(int x, struct AvlNode* t);
struct AvlNode* myDelete(int x, struct AvlNode* t);
void printAvl(struct AvlNode* t);

struct AvlNode
{
	int element;
	struct AvlNode* left;
	struct AvlNode* right;
	int height;
};

2、main函数

#include "AVL树.h"

int main()
{
	struct AvlNode* min;
	struct AvlNode* max;
	struct AvlNode* node;
	struct AvlNode* root;
	root = insert(6, NULL);
	insert(4, root);
	insert(3, root);
	insert(2, root);
	insert(1, root);
	insert(8, root);
	printAvl(root);

	//查找关键字为4的节点
	node = find(4, root);
	if (NULL == node) {
		printf("not find!\n");
	}
	else {
		printf("\nfind node is:%d\n", node->element);
	}

	//查找key最小的节点
	min = findMin(root);
	printf("min is:%d\n", min->element);

	//查找key最大的节点
	max = findMax(root);
	printf("max is:%d\n", max->element);

	return 0;
}

3、函数实现

3.1 makeEmpty.c

#include "AVL树.h"

struct AvlNode* makeEmpty(struct AvlNode* t)
{
	if (NULL != t)
	{
		makeEmpty(t->left);
		makeEmpty(t->right);
		free(t);
	}
	return NULL;
}

3.2 find.c

#include "AVL树.h"

struct AvlNode* find(int x, struct AvlNode* t)
{
	if (NULL == t) { ; }
	else if (x > t->element) {
		return find(x, t->right);
	}
	else if (x < t->element) {
		return find(x, t->left);
	}
	return t;
}

3.3 findMin.c

#include "AVL树.h"

struct AvlNode* findMin(struct AvlNode* t)
{
	if (NULL != t->left) {
		return findMin(t->left);
	}
	return t;
}

3.4 findMax.c

#include "AVL树.h"

struct AvlNode* findMax(struct AvlNode* t)
{
	if (NULL != t->right) {
		return findMax(t->right);
	}
	return t;
}

3.5 insert.c

#include "AVL树.h"
#define Max(v1, v2) (v1)>(v2)?(v1):(v2)

static int height(struct AvlNode* t);
static struct AvlNode* singleRotateWithLeft(struct AvlNode* k2);
static struct AvlNode* doubleRotateWithLeft(struct AvlNode* k3);
static struct AvlNode* singleRotateWithRight(struct AvlNode* k2);
static struct AvlNode* doubleRotateWithRight(struct AvlNode* k3);


struct AvlNode* insert(int x, struct AvlNode* t)
{
	if (NULL == t) {
		t = malloc(sizeof(struct AvlNode));
		if (NULL == t) {
			return NULL;
		}
		t->element = x;
		t->left = NULL;
		t->right = NULL;
		t->height = 0;
	}
	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);
			}
		}
	}
	else if (x < t->element) {
		t->left = insert(x, t->left);
		if (height(t->left) - height(t->right) == 2) {
			if (x < t->left->element) {
				t = singleRotateWithLeft(t);
			}
			else {
				t = doubleRotateWithLeft(t);
			}
		}
	}
	t->height = Max(height(t->left), height(t->right)) + 1;
	return t;
}

static int height(struct AvlNode* t)
{
	if (NULL == t) {
		return -1;
	}
	else {
		return t->height;
	}
}

//新增的值在左儿子的左子树
static struct AvlNode* singleRotateWithLeft(struct AvlNode* k2)
{
	struct AvlNode* k1;
	k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	k2->height = Max(height(k2->left), height(k2->left)) + 1;
	k1->height = Max(height(k1->left), k2->height) + 1;
	return k1;
}

//新增的值在右儿子的右子树
static struct AvlNode* singleRotateWithRight(struct AvlNode* k2)
{
	struct AvlNode* k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;
	k2->height = Max(height(k2->left), height(k2->right)) + 1;
	k1->height = Max(height(k1->right), k2->height) + 1;
	return k1;
}

//新增的值在左儿子的右子树
static struct AvlNode* doubleRotateWithLeft(struct AvlNode* k3)
{
	k3->left = singleRotateWithRight(k3->left);
	return singleRotateWithLeft(k3);
}

//新增的值在右儿子的左子树
static struct AvlNode* doubleRotateWithRight(struct AvlNode* k3)
{
	k3->right = singleRotateWithLeft(k3->right);
	return singleRotateWithRight(k3);
}

3.6 printAvl.c

#include "AVL树.h"

void printAvl(struct AvlNode* t)
{
	if (NULL == t) {
		printf("Empty AvlNode!\n");
		return;
	}
	//中序遍历
	if (t->left != NULL) {
		printAvl(t->left);
	}
	printf("%d ", t->element);
	if (t->right != NULL) {
		printAvl(t->right);
	}
	return t;
}

4、写在最后

为方便大家学习,我已经将原码上传到了GitHub,欢迎大家下载。链接:link