您的位置:首页 > 其它

AVL平衡树

2014-06-06 16:25 141 查看
#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

typedef struct treeItem {
ElementType e;
struct treeItem *left;
struct treeItem *right;
} TreeItem;

typedef TreeItem *Tree;

#define MAX(a, b) ((a) > (b) ? (a) : (b))

TreeItem *Find(Tree t, ElementType e)
{
while (t != NULL && e != t->e) {
if (e < t->e)
t = t->left;
else/* if (e > t->e) */
t = t->right;
}

return t;
}

TreeItem *FindMin(Tree t)
{
while (t && t->left) {
t = t->left;
}

return t;
}

TreeItem *FindMax(Tree t)
{
while (t && t->right) {
t = t->right;
}

return t;
}

TreeItem *SingleRotateWithLeft(TreeItem *p1)
{
TreeItem *p2;

p2 = p1->left;
p1->left = p2->right;
p2->right = p1;

return p2;
}

TreeItem *SingleRotateWithRight(TreeItem *p1)
{
TreeItem *p2;

p2 = p1->right;
p1->right = p2->left;
p2->left = p1;

return p2;
}

TreeItem *DoubleRotateWithLeft(TreeItem *p1)
{
// Rotate between p2 and p3
// 	p1->left = SingleRotateWithRight(p1->left);
// 	// Rotate between p1 and p2
// 	return SingleRotateWithLeft(p1);

TreeItem *p2 = p1->left;
TreeItem *p3 = p2->right;

p2->right = p3->left; // R
p3->left = p2;
p1->left = p3;

p1->left = p3->right; // L
p3->right = p1;

return p3;
}

TreeItem *DoubleRotateWithRight(TreeItem *p1)
{
p1->right = SingleRotateWithLeft(p1->right);
return SingleRotateWithRight(p1);
}

Tree AVLInsert(Tree t, ElementType e)
{
if (t == NULL) {
t = (TreeItem *)malloc(sizeof(treeItem));
if (!t) {
printf("malloc error!\n");
return NULL;
}
t->e = e;
t->left = t->right = NULL;
} else if (e < t->e) {
t->left = AVLInsert(t->left, e);
if ((GetHeight(t->left) - GetHeight(t->right)) == 2) {
if (e < t->left->e)  // LL
t = SingleRotateWithLeft(t);
else
t = DoubleRotateWithLeft(t); // LR
}
} else { // e >= t->e
t->right = AVLInsert(t->right, e);
if ((GetHeight(t->right) - GetHeight(t->left)) == 2) {
if (e > t->right->e) // RR
t = SingleRotateWithRight(t);
else
t = DoubleRotateWithRight(t); // RL
}
}

return t;
}

Tree AVLDelete(Tree t, ElementType e)
{
if (!t) {
printf("t is empty!\n");
} else if (e < t->e) {
t->left = AVLDelete(t->left, e);
if (GetHeight(t->right) - GetHeight((t->left)) == 2) {
TreeItem *p = t->right;
if (GetHeight(p->left) > GetHeight(p->right))
t = DoubleRotateWithRight(t);
else
t = SingleRotateWithRight(t);
}
} else if (e > t->e) {
t->right = AVLDelete(t->right, e);
if (GetHeight(t->left) - GetHeight((t->right)) == 2) {
TreeItem *p = t->left;
if (GetHeight(p->right) > GetHeight(p->left))
t = DoubleRotateWithLeft(t);
else
t = SingleRotateWithLeft(t);
}
} else { // e = t->e // fount it
if (t->left && t->right) { // 有两个孩子的情况
if (GetHeight(t->left) > GetHeight(t->right)) {  // 这里处理是关键
t->e = FindMax(t->left)->e;
t->left = AVLDelete(t->left, t->e);
} else {
t->e = FindMin(t->right)->e;
t->right = AVLDelete(t->right, t->e);
}
} else { // 只有一个孩子or没有孩子
TreeItem *pe = t;
t = t->left ? t->left : t->right;
free(pe);
}
}
return t;
}

#define BUFSIZE 10

int main()
{
int arr[BUFSIZE] = {19, 13, 23, 8, 17, 21, 43, 3, 11, 14};
Tree t = NULL;

printf("insert element:\n");
for (int i = 0; i < BUFSIZE; i++) {
t = AVLInsert(t, arr[i]);
printf("height:%d\n", GetHeight(t));
InorderTraversal1(t);
printf("\n");
}

printf("delete element:\n");
for (int i = 0; i < BUFSIZE; i++) {
t = AVLDelete(t, arr[i]);
printf("height:%d\n", GetHeight(t));
InorderTraversal(t);
printf("\n");
}

getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: