数据结构与算法分析——c语言描述 第四章树 AVL树
以往都是照抄书上的头文件,自己实现。但是这次avl树insert不会写,竟然抄了这个函数七八成的代码,思路被牵着走,删掉代码重新自己写。看思路,自己写代码,切记切记。其实还是很简单的,画个图什么都懂了。采用懒惰删除,查找函数分两个
然后有一个出了一个bug,死活找不到原因,最后看函数调用情况才找出来,树的高度要记得更新。
所以啊,代码一看就懂,所以自己独立写出来是很有必要的。
avlTree.h
typedef int ElementType;
#ifndef _AvlTree_H
#define _AvlTree_H
struct AvlNode;
typedef struct AvlNode *Position;
typedef struct AvlNode *AvlTree;
AvlTree createAvlTree();
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);
ElementType retrieve(Position p);
#endif
avlTree.c
#include"avlTree.h"
#include<stdlib.h>
#include"fatal.h"
struct AvlNode {
ElementType element;
AvlTree left;
AvlTree right;
int isDeleted;
int height;
};
static int height(Position p) {
if (p == NULL)
return -1;
else {
return p->height;
}
}
static int Max(int lhs, int rhs) {
return lhs > rhs ? lhs : rhs;
}
static Position singleRotateWithLeft(Position k2) {
Position k1 = k2->left;
Position y = k1->right;
k2->left = y;
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;
}
static Position singleRotateWithRight(Position k1) {
Position k2 = k1->right;
Position y = k2->left;
k1->right = y;
k2->left = k1;
k1->height = Max(height(k1->left), height(k1->right)) + 1;
k2->height = Max(height(k2->left), height(k2->right)) + 1;
return k2;
}
static Position doubleRotateWithLeft(Position k3) {
Position k1 = k3->left;
k3->left = singleRotateWithRight(k1);
return singleRotateWithLeft(k3);
}
static Position doubleRotateWithRight(Position k1) {
Position k3 = k1->right;
k1->right = singleRotateWithLeft(k3);
return singleRotateWithRight(k1);
}
AvlTree createAvlTree() {
return NULL;
}
AvlTree MakeEmpty(AvlTree T) {
if (T != NULL) {
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
return NULL;
}
static Position findIgnoreDel(ElementType X, AvlTree t) {
if (t == NULL)
return NULL;
else {
if (X <retrieve(t))
return findIgnoreDel(X, t->left);
else if (X>retrieve(t))
return findIgnoreDel(X, t->right);
else
return t;
}
}
Position find(ElementType X, AvlTree t) {
Position p = findIgnoreDel(X, t);
if (p&&p->isDeleted == 0)
return p;
else
return NULL;
}
Position findMin(AvlTree t) {
if (t) {
Position p = findMin(t->left);
if (p)
return p;
else if (t->isDeleted == 0)
return t;
else
return NULL;
}
return NULL;
}
Position findMax(AvlTree t) {
if (t) {
Position p = findMax(t->right);
if (p)
return p;
else if (t->isDeleted == 0)
return t;
else
return NULL;
}
return NULL;
}
AvlTree insert(ElementType X, AvlTree t) {
if (t == NULL) {
t = malloc(sizeof(struct AvlNode));
if (t == NULL)
Error("out of memory");
t->element = X;
t->left = NULL;
t->right = NULL;
t->height = 0;
t->isDeleted = 0;
}
else if (X < retrieve(t)) {
t->left = insert(X, t->left);
if (height(t->left) - height(t->right) == 2) {
if (X < retrieve(t->left)) {
t = singleRotateWithLeft(t);
}
else
t = doubleRotateWithLeft(t);
}
}
else if ( X >retrieve(t)) {
t->right = insert(X, t->right);
if (height(t->right) - height(t->left) == 2) {
if (X > retrieve(t->right))
t = singleRotateWithRight(t);
else
t = doubleRotateWithRight(t);
}
}
else {
t->isDeleted = 0;
}
t->height = Max(height(t->left), height(t->right)) + 1;
return t;
}
AvlTree Delete(ElementType X, AvlTree t) {
Position p = findIgnoreDel(X, t);
p->isDeleted = 1;
return p;
}
ElementType retrieve(Position p) {
return p->element;
}
main.c
#include"avlTree.h"
#include<stdio.h>
#include<stdlib.h>
struct AvlNode {
ElementType element;
AvlTree left;
AvlTree right;
int isDeleted;
int height;
};
int main() {
AvlTree t = createAvlTree();
for (int i = 1; i < 1234567; i++) {
t= insert(rand(), t);
}
printf("%d",t->height);
}