数据结构与算法分析——c语言描述 练习4.20 答案
很惭愧,没有想出思路。网上看了别人(CSDN的 ljianhui)的思路自己写了代码。删除左边不平衡时相当于在右边插入。然后就是通过右儿子的两个子树判断是要单还是右旋转。
avltree.c
#include"avlTree.h"
#include<stdlib.h>
#include"fatal.h"
struct AvlNode {
ElementType element;
AvlTree left;
AvlTree right;
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 find(ElementType X, AvlTree t) {
if (t == NULL)
return NULL;
else {
if (X <retrieve(t))
return find(X, t->left);
else if (X>retrieve(t))
return find(X, t->right);
else
return t;
}
}
Position findMin(AvlTree t) {
if (t) {
Position p = findMin(t->left);
if (p)
return p;
else
return t;
}
return NULL;
}
Position findMax(AvlTree t) {
if (t) {
Position p = findMax(t->right);
if (p)
return p;
else
return t;
}
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;
}
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 {//已存在
return t;
}
t->height = Max(height(t->left), height(t->right)) + 1;
return t;
}
AvlTree Delete(ElementType X, AvlTree t) {
Position tempCell;
if (t == NULL) {
fprintf(stderr, "ELEMENT NOT FOUND\n");
}
else if (X < t->element) {
t->left = Delete(X, t->left);
if (height(t->right) - height(t->left) == 2) {
if (height(t->right->right) > height(t->right->left))//右子树的右子树比右子树的左子树高,相对于右右插入
t = singleRotateWithRight(t);
else
t = doubleRotateWithRight(t);
}
t->height = Max(height(t->left), height(t->right)) + 1;
}
else if (X > t->element) {
t->right = Delete(X, t->right);
if (height(t->left) - height(t->right) == 2) {
if (height(t->left->left) > height(t->left->right))//左子树的左子树比左子树的右子树高,相对于左左插入
t = singleRotateWithLeft(t);
else
t = doubleRotateWithLeft(t);
}
t->height = Max(height(t->left), height(t->right)) + 1;
}
else if (t->left && t->right) {
tempCell = findMin(t->right);
t->element = tempCell->element;
t->right = Delete(t->element, t->right);
t->height = Max(height(t->left), height(t->right)) + 1;
}
else {
tempCell = t;
if (t->left == NULL) {
t = t->right;
}
else if (t->right == NULL) {
t = t->left;
}
free(tempCell);
}
return t;
}
ElementType retrieve(Position p) {
return p->element;
}
void dir(AvlTree t) {
if (t) {
printf("%d ", t->element);
dir(t->left);
dir(t->right);
}
}