这里只介绍生成AVL树的代码。
AVL树插入先按照普通有序二叉树的方法插入节点。插入了之后,父节点新插入方向上的子树高度增1。如果是左侧,平衡因子–,右侧++。++和–都代表某侧的高度在增加。
AVL树允许两边子树有1层差距,超过之后需要调整。细分有LL型,LR型,RL型,RR型,4种情况。调整是对2-3个节点局部中序重排。LL型RR型调整2个节点,有一个子树迁移,LR型RL型调整3个节点,有两个子树迁移。重排后原则上每个节点的平衡因子都为0, 除了LR型RL型中间那个节点两个子树不一样高的情况, 这时除了矮的那棵子树, 这些节点周围的其他3个子树都一样高。
下面是code:
#include <stdio.h>
struct node {
int key;
int tag;
struct node *parent;
struct node *left;
struct node *right;
};
struct tree_rec {
struct node *root;
};
插入操作:
int insert(struct tree_rec *tree, int key)
{
struct node *p;
struct node *next;
struct node *left, *right, *mid;
p = tree->root;
loc:
if (key> p->key) next = p->right;
else if(key <p->key) next = p->left;
else return 0;
if (next) {
p = next;
goto loc;
}
next = (struct node*) malloc(sizeof(struct node));
next->key=key;
next->tag=0;
next->parent=p;
next->left=next->right=NULL;
if (key>p->key) {
p->right=next;
p->tag++;
}
else {
p->left=next;
p->tag--;
}
up:
if (p->tag==0) return 1;
next = p->parent;
if (next == NULL)return 1;
if (p==next->left) next->tag--;
else next->tag++;
if (next->tag==2) {
if (p->tag==1) {
left = p->left;
p->left = next;
next->right= left;
if (left) left->parent=next;
p->tag=0;
next->tag=0;
if( next->parent==NULL) {
p->parent=NULL;
tree->root=p;
}
else {
p->parent=next->parent;
if (next==next->parent->left)
next->parent->left =p;
else next->parent->right=p;
}
next->parent=p;
return 1;
}
else { /* p->tag==-1 */
mid = p->left;
left = mid->left;
right = mid->right;
mid->left = next;
mid->right = p;
next->right = left;
if(left) left->parent = next;
p->left = right;
if(right) right->parent =p;
if (mid->tag==0) {
next->tag=p->tag=mid->tag=0;
}
else if(mid->tag==1) {
next->tag=-1;
p->tag=mid->tag=0;
}
else {
next->tag = mid->tag=0;
p->tag = 1;
}
if (next->parent==NULL) {
mid->parent = NULL;
tree->root = mid;
}
else {
mid->parent = next->parent;
if (next==next->parent->left)
next->parent->left =mid;
else next->parent->right=mid;
}
next->parent = mid;
p->parent = mid;
return 1;
}
}
else if(next->tag==-2) {
if (p->tag==-1) {
right = p->right;
p->right = next;
next->left= right;
if (right) right->parent=next;
p->tag=0;
next->tag=0;
if( next->parent==NULL) {
p->parent=NULL;
tree->root=p;
}
else {
p->parent=next->parent;
if (next==next->parent->left)
next->parent->left =p;
else next->parent->right=p;
}
next->parent=p;
return 1;
}
else { /* p->tag==1 */
mid = p->right;
left = mid->left;
right = mid->right;
mid->left = p;
mid->right = next;
p->right = left;
if(left) left->parent = p;
next->left = right;
if(right) right->parent =next;
if (mid->tag==0) {
next->tag=p->tag=mid->tag=0;
}
else if(mid->tag==1) {
p->tag=-1;
next->tag=mid->tag=0;
}
else {
p->tag = mid->tag=0;
next->tag = 1;
}
if (next->parent==NULL) {
mid->parent = NULL;
tree->root = mid;
}
else {
mid->parent = next->parent;
if (next==next->parent->left)
next->parent->left =mid;
else next->parent->right=mid;
}
next->parent = mid;
p->parent = mid;
return 1;
}
}
else {
p = next;
goto up;
}
}
以下测试代码:
int keys[] = {
35, 36, 37, 38, 39, 40,
8,9,10, 11,12, 13, 14,
41,42, 43,44,45,
58,59,60,
1, 2,3,4, 5, 6, 7,
21, 22, 23, 24, 25, 26,27,
15, 16, 17,18, 19, 20,
51,52,53,54,55,56,57,
28, 29, 30, 31, 32, 33, 34,
46,47,48,49, 50,
};
int level(struct node *p)
{
int i=0;
while (p){
++i;
p= p->parent;
}
return i-1;
}
void printtree(struct tree_rec *tree)
{
struct node *p;
int i;
int curlevel;
struct node *queue[200];
int first, last;
first=last=0;
curlevel=0;
p = tree->root;
if(p) {
printf("%d: ", curlevel);
printf("%d",p->key);
if(p->left) queue[last++] = p->left;
if(p->right) queue[last++] = p->right;
}
while(first<last) {
p = queue[first++];
if (level(p)>curlevel) {
printf("\n");
curlevel++;
printf("%d:", curlevel);
}
if(p==p->parent->left) printf(" %d(<-%d)",p->key,p->parent->key)
;
else printf(" (%d->)%d",p->parent->key,p->key);
if(p->left) queue[last++] = p->left;
if(p->right) queue[last++] = p->right;
}
printf("\n");
}
int main()
{
struct tree_rec r;
int i;
srand(time(0));
for(i=0; i<20; i++) {
int a, b;
a= rand()%(sizeof(keys)/sizeof(int));
b= rand()%(sizeof(keys)/sizeof(int));
if (a!=b) {
int t;
t=keys[a];
keys[a]=keys[b];
keys[b]=t;
}
}
r.root = (struct node*)malloc(sizeof(struct node));
r.root->key=keys[0];
r.root->tag=0;
r.root->parent=NULL;
r.root->left=r.root->right=NULL;
for( i=1; i<60; i++) {
insert( &r, keys[i]);
printtree(&r);
}
return 0;
}