AVL树,C语言实现,完整代码,先贴上,讲解稍后
Posted gaussianprince
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AVL树,C语言实现,完整代码,先贴上,讲解稍后相关的知识,希望对你有一定的参考价值。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#define ADD_FOUND 0
#define ADD_ALLOC_FAILED 1
#define ADD_ROOT 2
#define ADD_NORMAL 3
#define ADD_RLNULL 4
#define ADD_LRNULL 5
#define DEL_LLNULL 6
#define DEL_LRNULL 7
#define DEL_RRNULL 8
#define DEL_RLNULL 9
#define DEL_NOTFOUND 10
#define DEL_ROOT 11
#define DEL_NORMAL 12
#define ADD_PARAERROR 13
#define DEL_PARAERROR 14
#define DEL_LCHILDNULL 15
#define DEL_RCHILDNULL 16
typedef struct _avl_node
struct _avl_node *lchild;
struct _avl_node *rchild;
struct _avl_node *parent;
int value;
int bf;
avl_node;
avl_node *avl_root = 0;
static inline void rotate_left(avl_node *node)
avl_node *rnode;
avl_node *pnode;
if (!node || !node->rchild)return;
rnode = node->rchild;
pnode = node->parent;
if (pnode)
if (pnode->lchild == node)pnode->lchild = rnode;
else if (pnode->rchild == node)pnode->rchild = rnode;
else
avl_root = rnode;
rnode->parent = pnode;
node->rchild = rnode->lchild;
node->parent = rnode;
if (rnode->lchild)rnode->lchild->parent = node;
rnode->lchild = node;
static inline void rotate_right(avl_node *node)
avl_node *lnode;
avl_node *pnode;
if (!node || !node->lchild)return;
lnode = node->lchild;
pnode = node->parent;
if (pnode)
if (pnode->lchild == node)pnode->lchild = lnode;
else if (pnode->rchild == node)pnode->rchild = lnode;
else
avl_root = lnode;
lnode->parent = pnode;
node->lchild = lnode->rchild;
node->parent = lnode;
if (lnode->rchild)lnode->rchild->parent = node;
lnode->rchild = node;
static inline int add_avl_fixup(avl_node *node)
avl_node *pnode;
avl_node *child;
avl_node *tmp;
if (!node)return ADD_PARAERROR;
pnode = node->parent;
child = node;
while (pnode)
if (pnode->bf == 0)return ADD_NORMAL;
if (pnode->bf == 2)
if (pnode->lchild)
switch (pnode->lchild->bf)
case 1:
if (pnode->lchild->lchild)
pnode->lchild->bf = 0;
pnode->bf = 0;
rotate_right(pnode);
if (pnode->bf >= 2 || pnode->bf <= -2)
printf("ll error\n");
else
printf("ADD_LLNULL\n");
break;
case -1:
if (pnode->lchild->rchild)
if (pnode->lchild->rchild->bf == -1)
pnode->bf = 0;
pnode->lchild->bf = 1;
else if (pnode->lchild->rchild->bf == 1)
pnode->bf = -1;
pnode->lchild->bf = 0;
else if (pnode->lchild->rchild->bf == 0)
pnode->bf = 0;
pnode->lchild->bf = 0;
pnode->lchild->rchild->bf = 0;
tmp = pnode;
rotate_left(pnode->lchild);
rotate_right(tmp);
if (pnode->bf >= 2 || pnode->bf <= -2)
printf("lr error\n");
else
printf("ADD_LRNULL\n");
return ADD_LRNULL;
break;
else
printf("2 not change\n");
return ADD_NORMAL;
else if (pnode->bf == -2)
if (pnode->rchild)
switch (pnode->rchild->bf)
case -1:
if (pnode->rchild->rchild)
pnode->bf = 0;
pnode->rchild->bf = 0;
rotate_left(pnode);
if (pnode->bf >= 2||pnode->bf<=-2)
printf("rr error\n");
else
printf("ADD_RRNULL\n");
break;
case 1:
if (pnode->rchild->lchild)
if (pnode->rchild->lchild->bf == 1)
pnode->bf = 0;
pnode->rchild->bf = -1;
else if (pnode->rchild->lchild->bf == -1)
pnode->bf = 1;
pnode->rchild->bf = 0;
else if (pnode->rchild->lchild->bf == 0)
pnode->bf = 0;
pnode->rchild->bf = 0;
pnode->rchild->lchild->bf = 0;
tmp = pnode;
rotate_right(pnode->rchild);
rotate_left(tmp);
if (pnode->bf >= 2 || pnode->bf <= -2)
printf("rl error\n");
else
printf("ADD_RLNULL\n");
return ADD_RLNULL;
break;
else
printf("-2 not change\n");
return ADD_NORMAL;
child = pnode;
pnode = pnode->parent;
if (pnode)
if (pnode->bf == 2 || pnode->bf == -2)
if (pnode->lchild == child)
pnode->bf += 1;
else if (pnode->rchild == child)
pnode->bf -= 1;
int add_avl_node(avl_node**proot, int val,int seq)
static int counter = 0;
avl_node *root;
avl_node *pre;
avl_node *nnode;
if (!proot)return ADD_PARAERROR;
root = *proot;
pre = root;
while (root)
pre = root;
if (root->value > val)root = root->lchild;
else if (root->value < val)root = root->rchild;
else return ADD_FOUND;
++counter;
nnode = (avl_node *)malloc(sizeof(avl_node));
if (!nnode)return ADD_ALLOC_FAILED;
memset(nnode, 0, sizeof(avl_node));
nnode->value = val;
nnode->bf = 0;
nnode->parent = 0;
nnode->lchild = 0;
nnode->parent = 0;
if (pre == 0)
*proot = nnode;
return ADD_ROOT;
if (pre->value > val)
if (pre->bf >= 1)
printf("NOT 1 %d 0x%x\n",counter,(unsigned int)pre->lchild);
pre->bf += 1;
pre->lchild = nnode;
else if (pre->value < val)
if (pre->bf <= -1)
printf("NOT -1 %d 0x%x\n",counter,(unsigned int)pre->rchild);
pre->bf -= 1;
pre->rchild = nnode;
nnode->parent = pre;
return add_avl_fixup(nnode);
static inline int del_avl_fixup(avl_node *node)
avl_node *pnode;
avl_node *child;
if (!node)return DEL_PARAERROR;
pnode = node;
while (pnode)
if (pnode->bf == 2)
if (!pnode->lchild)
printf("pnode->lchild is null\n");
return DEL_LCHILDNULL;
if (pnode->lchild->bf == 0)
pnode->bf = 1;
pnode->lchild->bf = -1;
rotate_right(pnode);
return DEL_NORMAL;
else if (pnode->lchild->bf == 1)
pnode->bf = 0;
pnode->lchild->bf = 0;
child = pnode->lchild;
rotate_right(pnode);
pnode = child;
else if (pnode->lchild->bf == -1)
if (pnode->lchild->rchild)
if (pnode->lchild->rchild->bf == 1)
pnode->lchild->bf = 0;
pnode->bf = -1;
else if (pnode->lchild->rchild->bf == -1)
pnode->lchild->bf = 1;
pnode->bf = 0;
else if (pnode->lchild->rchild->bf == 0)
pnode->lchild->bf = 0;
pnode->bf = 0;
pnode->lchild->rchild->bf = 0;
child = pnode->lchild->rchild;
rotate_left(pnode->lchild);
rotate_right(pnode);
pnode = child;
else
printf("DEL LR NULL\n");
return DEL_LRNULL;
else if (pnode->bf == -2)
if (!pnode->rchild)
printf("pnode->rchild is null\n");
return DEL_RCHILDNULL;
if (pnode->rchild->bf == 0)
pnode->bf = -1;
pnode->rchild->bf = 1;
rotate_left(pnode);
return DEL_NORMAL;
else if (pnode->rchild->bf == 1)
if (pnode->rchild->lchild)
if (pnode->rchild->lchild->bf == 1)
pnode->bf = 0;
pnode->rchild->bf = -1;
else if (pnode->rchild->lchild->bf == -1)
pnode->bf = 1;
pnode->rchild->bf = 0;
else if (pnode->rchild->lchild->bf == 0)
pnode->bf = 0;
pnode->rchild->bf = 0;
pnode->rchild->lchild->bf = 0;
child = pnode->rchild->lchild;
rotate_right(pnode->rchild);
rotate_left(pnode);
pnode = child;
else
printf("DEL RL NULL\n");
return DEL_RLNULL;
else if (pnode->rchild->bf == -1)
pnode->bf = 0;
pnode->rchild->bf = 0;
child = pnode->rchild;
rotate_left(pnode);
pnode = child;
else if (pnode->bf == -1 || pnode->bf == 1)
return DEL_NORMAL;
else if (pnode->bf > 2 || pnode->bf < -2)
printf("DEL INVALID bf %d\n", pnode->bf);
if (pnode->parent)
if (pnode->parent->lchild == pnode)pnode->parent->bf -= 1;
else if (pnode->parent->rchild == pnode)pnode->parent->bf += 1;
pnode = pnode->parent;
return DEL_NORMAL;
int del_avl_node(avl_node **proot,int val)
avl_node *root;
avl_node *post;
avl_node *pnode=0;
if (!proot||!(*proot))return DEL_PARAERROR;
root = *proot;
while (root)
if (root->value > val)root = root->lchild;
else if (root->value < val)root = root->rchild;
else break;
if (!root)return DEL_NOTFOUND;
if (!root->lchild)
if (root->parent)
if (root->parent->lchild == root)
root->parent->bf -= 1;
if (root->rchild)root->rchild->parent = root->parent;
root->parent->lchild = root->rchild;
else if (root->parent->rchild == root)
root->parent->bf += 1;
if (root->rchild)root->rchild->parent = root->parent;
root->parent->rchild = root->rchild;
pnode = root->parent;
memset(root, 0, sizeof(avl_node));
free(root);
else
if (root->rchild)root->rchild->parent = 0;
*proot = root->rchild;
printf("L NULL P NULL\n");
memset(root, 0, sizeof(avl_node));
free(root);
return DEL_NORMAL;
else if (!root->rchild)
if (root->parent)
if (root->parent->lchild == root)
root->parent->bf -= 1;
if (root->lchild)root->lchild->parent = root->parent;
root->parent->lchild = root->lchild;
else if (root->parent->rchild == root)
root->parent->bf += 1;
if (root->lchild)root->lchild->parent = root->parent;
root->parent->rchild = root->lchild;
pnode = root->parent;
memset(root, 0, sizeof(avl_node));
free(root);
else
if (root->lchild)root->lchild->parent = 0;
*proot = root->rchild;
printf("R NULL P NULL\n");
memset(root, 0, sizeof(avl_node));
free(root);
return DEL_NORMAL;
else
post = root->rchild;
while (post->lchild)post = post->lchild;
root->value = post->value;
if (post->parent->lchild==post)
post->parent->bf -= 1;
post->parent->lchild = post->rchild;
if (post->rchild)
post->rchild->parent = post->parent;
else if (post->parent->rchild == post)
post->parent->bf += 1;
post->parent->rchild = post->rchild;
if (post->rchild)
post->rchild->parent = post->parent;
pnode = post->parent;
memset(post, 0, sizeof(avl_node));
free(post);
return del_avl_fixup(pnode);
static void cal_avl_deepth(avl_node *root,int *total,int *deepth)
int last_deepth = 1;
char flag = 0;
avl_node *post;
char buf[128];
FILE *fp;
if (!root)return;
deepth[0] = 1;
memset(buf, 0, sizeof(buf));
sprintf(buf, ".\\%u", time(0));
if ((fp = fopen(buf, "w")) == 0)
printf("Failed to open file\n");
return;
while (root)
while (root->lchild&&flag!=100)
root = root->lchild;
deepth[0]++;
if (last_deepth < deepth[0])last_deepth = deepth[0];
if (root->parent == 0)printf("Visit root:%d\n", deepth[0]);
total[0]++;
fprintf(fp, "%d ", root->value);
if (!root->rchild)
while (root->parent&&root->parent->rchild == root)
root = root->parent;
deepth[0]--;
deepth[0]--;
root = root->parent;
flag = 100;
else
deepth[0]++;
root = root->rchild;
flag = 0;
deepth[0] = last_deepth;
fclose(fp);
int main(void)
int i = 0;
int total_avl_node = 0;
int avl_deepth = 0;
srand(time(0));
for (i = 0; i < 10000000;i++)
add_avl_node(&avl_root, rand()%0x7fffffff,i);
del_avl_node(&avl_root, rand() % 0x7fffffff);
cal_avl_deepth(avl_root, &total_avl_node, &avl_deepth);
printf("total:%d deepth:%d\n", total_avl_node, avl_deepth);
for (i = 0; i < 0x7fffffff; i++)
del_avl_node(&avl_root, i);
total_avl_node = 0;
avl_deepth = 0;
cal_avl_deepth(avl_root, &total_avl_node, &avl_deepth);
printf("total:%d deepth:%d\n", total_avl_node, avl_deepth);
while (1)
return 0;
以上是关于AVL树,C语言实现,完整代码,先贴上,讲解稍后的主要内容,如果未能解决你的问题,请参考以下文章