版本1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
typedef struct node node;
struct node
{
node* parent;
node* left;
node* right;
int balance; //左右子树高度之差
int key;
};
extern void traverseAVL1(node* root); //中序遍历, 下面定义
extern void traverseAVL2(node* root); //前序遍历, 下面定义
int searchNode(int key, node* root, node** parent) //按key查找结点
{
node* temp;
assert(root != NULL);
temp = root;
*parent = root->parent;
while (temp !=NULL)
{
if (temp->key == key)
return 1;
else
{
*parent = temp;
if (temp->key > key)
temp = temp->left;
else
temp = temp->right;
}
}
return 0;
}
node* minNode(node* root) //树root的最小结点
{
if (root == NULL)
return NULL;
while (root->left != NULL)
root = root->left;
return root;
}
node* maxNode(node* root) //树root的最大结点
{
if (root == NULL)
return NULL;
while (root->right != NULL)
root = root->right;
return root;
}
node* preNode(node* target) //求前驱结点
{
if (target == NULL)
return NULL;
if (target->left != NULL)
return maxNode(target->left);
else
while ((target->parent!=NULL) && (target!=target->parent->right))
target = target->parent;
return target->parent;
}
node* nextNode(node* target) //求后继结点
{
if (target == NULL)
return NULL;
if (target->right != NULL)
return minNode(target->right);
else
while ((target->parent!=NULL) && (target!=target->parent->left))
target = target->parent;
return target->parent;
}
node* adjustAVL(node* root, node* parent, node* child)
{
node *cur;
assert((parent != NULL)&&(child != NULL));
switch (parent->balance)
{
case 2:
if (child->balance == -1)//LR型
{
cur = child->right;
cur->parent = parent->parent;
child->right = cur->left;
if (cur->left != NULL)
cur->left->parent = child;
parent->left = cur->right;
if (cur->right != NULL)
cur->right->parent = parent;
cur->left = child;
child->parent = cur;
cur->right = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = cur;
else parent->parent->right = cur;
else
root = cur;
parent->parent = cur;
if (cur->balance == 0)
{
parent->balance = 0;
child->balance = 0;
}
else if (cur->balance == -1)
{
parent->balance = 0;
child->balance = 1;
}
else
{
parent->balance = -1;
child->balance = 0;
}
cur->balance = 0;
}
else //LL型
{
child->parent = parent->parent;
parent->left = child->right;
if (child->right != NULL)
child->right->parent = parent;
child->right = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = child;
else parent->parent->right = child;
else
root = child;
parent->parent = child;
if (child->balance == 1) //插入时
{
child->balance = 0;
parent->balance = 0;
}
else //删除时
{
child->balance = -1;
parent->balance = 1;
}
}
break;
case -2:
if (child->balance == 1) //RL型
{
cur = child->left;
cur->parent = parent->parent;
child->left = cur->right;
if (cur->right != NULL)
cur->right->parent = child;
parent->right = cur->left;
if (cur->left != NULL)
cur->left->parent = parent;
cur->left = parent;
cur->right = child;
child->parent = cur;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = cur;
else parent->parent->right = cur;
else
root = cur;
parent->parent = cur;
if (cur->balance == 0)
{
parent->balance = 0;
child->balance = 0;
}
else if (cur->balance == 1)
{
parent->balance = 0;
child->balance = -1;
}
else
{
parent->balance = 1;
child->balance = 0;
}
cur->balance = 0;
}
else //RR型
{
child->parent = parent->parent;
parent->right = child->left;
if (child->left != NULL)
child->left->parent = parent;
child->left = parent;
if (parent->parent != NULL)
if (parent->parent->left == parent)
parent->parent->left = child;
else parent->parent->right = child;
else
root = child;
parent->parent = child;
if (child->balance == -1) //插入时
{
child->balance = 0;
parent->balance = 0;
}
else //删除时
{
child->balance = 1;
parent->balance = -1;
}
}
break;
}
return root;
}
node* insertNode(int key, node* root)
{
node *parent, *cur, *child;
assert (root != NULL);
if (searchNode(key, root, &parent)) //结点已存在
return root;
else
{
cur = (node*)malloc(sizeof(node));
cur->parent = parent;
cur->key = key;
cur->left = NULL;
cur->right = NULL;
cur->balance = 0;
if (key<parent->key)
{
parent->left = cur;
child = parent->left;
}
else
{
parent->right = cur;
child = parent->right;
}
while ((parent != NULL)) //查找需要调整的最小子树
{
if (child == parent->left)
if (parent->balance == -1)
{
parent->balance = 0;
return root;
}
else if (parent->balance == 1)
{
parent->balance = 2;
break;
}
else
{
parent->balance = 1;
child = parent;
parent = parent->parent;
}
else if (parent->balance == 1)
{
parent->balance = 0;
return root;
}
else if (parent->balance == -1)
{
parent->balance = -2;
break;
}
else
{
parent->balance = -1;
child = parent;
parent = parent->parent;
}
}
if (parent == NULL)
return root;
return adjustAVL(root, parent, child);
}
}
node* deleteNode(int key, node* root)
{
node *dNode, *parent, *child, *tp;
int temp, tc;
assert(root!=NULL);
if (!searchNode(key, root, &parent))
return root;
else
{
if (parent == NULL)
dNode = root;
else if ((parent->left!=NULL)&&(parent->left->key==key))
dNode = parent->left;
else dNode = parent->right;
child = dNode;
while ((child->left!=NULL)||(child->right!=NULL)) //确定需要删除的结点
{
if (child->balance == 1)
child = preNode(dNode);
else child = nextNode(dNode);
temp = child->key;
child->key = dNode->key;
dNode->key = temp;
dNode = child;
}
child = dNode;
parent = dNode->parent;
while ((parent != NULL)) //查找需要调整的最小子树
{
if (child == parent->left)
if (parent->balance == 1)
{
parent->balance = 0;
child = parent;
parent = parent->parent;
}
else if (parent->balance == -1)
{
parent->balance = -2;
child = parent->right;
temp = parent->right->balance;//临时变量保存
tp = parent->parent;//临时变量保存
if (tp != NULL)
if (parent == tp->left)
tc = 1;
else tc = -1;
else tc = 0;
root = adjustAVL(root, parent, child);
if (temp == 0)
break;
else
{
if (tc == 1)
child = tp->left;
else if (tc == -1)
child = tp->right;
parent = tp;
}
}
else
{
parent->balance = -1;
break;
}
else if (parent->balance == -1)
{
parent->balance = 0;
child = parent;
parent = parent->parent;
}
else if (parent->balance == 1)
{
parent->balance = 2;
child = parent->left;
temp = parent->left->balance;//临时变量保存
tp = parent->parent;//临时变量保存
if (tp != NULL)
if (parent == tp->left)
tc = 1;
else tc = -1;
else tc = 0;
root = adjustAVL(root, parent, child);
if (temp == 0)
break;
else
{
if (tc == 1)
child = tp->left;
else if (tc == -1)
child = tp->right;
parent = tp;
}
}
else
{
parent->balance = 1;
break;
}
}
if (dNode->parent != NULL)
if (dNode == dNode->parent->left)
dNode->parent->left = NULL;
else dNode->parent->right = NULL;
free(dNode);
if (root == dNode)
root = NULL; //root被删除, 避免野指针
dNode = NULL;
return root;
}
}
node* createAVL(int *data, int size)
{
int i, j;
node *root;
if (size<1)
return NULL;
root = (node*)malloc(sizeof(node));
root->parent = NULL;
root->left = NULL;
root->right = NULL;
root->key = data[0];
root->balance = 0;
for(i=1;i<size;i++)
root = insertNode(data[i], root);
return root;
}
void destroyAVL(node* root)
{
if (root != NULL)
{
destroyAVL(root->left);
destroyAVL(root->right);
free(root);
root=NULL;
}
}
void traverseAVL1(node* root) //中序遍历
{
if (root != NULL)
{
traverseAVL1(root->left);
printf("%d, %d\n", root->key, root->balance);
traverseAVL1(root->right);
}
}
void traverseAVL2(node* root) //先序遍历
{
if (root != NULL)
{
printf("%d, %d\n", root->key, root->balance);
traverseAVL2(root->left);
traverseAVL2(root->right);
}
}
int main(int argc, char *argv[])
{
int data[] = {1, 5, 7, 4, 3, 2, 11, 9, 10};
node* root;
root = createAVL(data, sizeof(data)/sizeof(data[0]));
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(5, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(3, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(1, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(7, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(4, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
root = deleteNode(2, root);
printf("++++++++++++++++++++++++++++\n");
traverseAVL1(root);
printf("\n");
traverseAVL2(root);
destroyAVL(root);
}
版本2:
#include <stdio .h>
#include <stdbool .h>
#include <stdlib .h>
char chos;
int input;
bool unbalanced = false;
struct node{
int data;
int bf;
node *lchild;
node *rchild;
};
typedef struct node *BST;
BST R = NULL;
void Chose(){
printf("i) Insert a point\n"
"d) Delete a point\n"
"e) exit\n"
"Input your choose:");
scanf(" %c", &chos);
}
int Height(BST T){ /*返回当前节点的高度*/
if(T == NULL)
return -1;
else
return T->bf;
}
int Max(int A, int B){
return ((A > B) ? A:B);
}
BST SingleRotateWithRight(BST K2){ /*RR型旋转*/
BST K1;
K1 = K2->rchild;
K2->rchild = K1->lchild;
K1->lchild = K2;
K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1;
K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1;
return K1;
}
BST SingleRotateWithLeft(BST K2){ /*LL型旋转*/
BST K1;
K1 = K2->lchild;
K2->lchild = K1->rchild;
K1->rchild = K2;
K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1;
K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1;
return K1;
}
BST DoubleRotateWithLeft(BST K3){ /*LR = RR(K3->lchild) + LL(K3)*/
K3->lchild = SingleRotateWithRight(K3->lchild);
return SingleRotateWithLeft(K3);
}
BST DoubleRotateWithRight(BST K3){ /*LL = LL(K3->lchild) + RR(K3)*/
K3->rchild = SingleRotateWithLeft(K3->rchild);
return SingleRotateWithRight(K3);
}
void OUT(BST T){ /*树的输出递归函数*/
if(T->lchild){
printf("Left\t%d\t[parent:%d]\n", T->lchild->data, T->data);
OUT(T->lchild);
}
if(T->rchild){
printf("Right\t%d\t[parent:%d]\n", T->rchild->data, T->data);
OUT(T->rchild);
}
}
BST Rotate(BST T){ /*对于单个节点进行的AVL调整*/
if(Height(T->lchild) - Height(T->rchild) == 2){
if(Height(T->lchild->lchild) >= Height(T->lchild->rchild)){
T = SingleRotateWithLeft(T);
}
else{
T = DoubleRotateWithLeft(T);
}
}
if(Height(T->rchild) - Height(T->lchild) ==2){
if(Height(T->rchild->rchild) >= Height(T->rchild->lchild)){
T = SingleRotateWithRight(T);
}
else{
T = DoubleRotateWithRight(T);
}
}
return T;
}
BST AVLInsert(BST T){ /*AVL数的插入操作*/
if(T == NULL){
T = (BST)malloc(sizeof(struct node));
T->data = input;
T->lchild = T->rchild = NULL;
T->bf = 0;
}
else if(input < T->data){
T->lchild = AVLInsert(T->lchild);
if(Height(T->lchild) - Height(T->rchild) == 2){
if(input < T->lchild->data){
T = SingleRotateWithLeft(T); /*LL旋转*/
}
else{
T = DoubleRotateWithLeft(T); /*LR旋转*/
}
}
}
else if(input > T->data){
T->rchild = AVLInsert(T->rchild);
if(Height(T->rchild) - Height(T->lchild) == 2){
if(input > T->rchild->data){
T = SingleRotateWithRight(T); /*RR旋转*/
}
else{
T = DoubleRotateWithRight(T); /*RL旋转*/
}
}
}
T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;
return T;
}
void Output(BST T){
if(T == NULL){
printf("None\n");
}
else{
printf("%d\troot\n", T->data);
OUT(T);
}
}
void Insert(){
printf("\nInput the point your want to Insert: ");
scanf("%d", &input);
R = AVLInsert(R);
Output(R);
}
BST AVLDelete(BST T, int key){
if(T == NULL)
return NULL;
if(key == T->data){
if(T->rchild == NULL){ /*如果T得右儿子为空则直接删除*/
BST temp = T;
T = T->lchild;
free(temp);
}
else{ /*否则找到T->rchild的最左儿子代替T*/
BST temp = T->rchild;
while(temp->lchild != NULL){
temp = temp->lchild;
}
T->data = temp->data;
T->rchild = AVLDelete(T->rchild, temp->data); /*对于替代后的T及其各个子节点进行一些列调整,正到再次递归到T->rchild的最左儿子,删除它*/
T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;
}
return T;
}
else if(key < T->data){
T->lchild = AVLDelete(T->lchild, key);
}
else{
T->rchild = AVLDelete(T->rchild, key);
}
T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;
if(T->lchild != NULL){
T->lchild = Rotate(T->lchild);
}
if(T->rchild != NULL){
T->rchild = Rotate(T->rchild);
}
T = Rotate(T);
return T;
}
void Delete(){
printf("\nInput the point you want to Delete: ");
scanf("%d", &input);
R = AVLDelete(R, input);
Output(R);
}
int main(){
while(1){
Chose();
switch(chos){
case 'i':
Insert();
break;
case 'd':
Delete();
break;
case 'e':
exit(0);
}
}
return 0;
}