AVL树实现非懒惰删除

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



你可能感兴趣的:(AVL树实现非懒惰删除)