数据结构与算法分析——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; }
#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); }