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语言实现,完整代码,先贴上,讲解稍后的主要内容,如果未能解决你的问题,请参考以下文章

C++AVL树的实现--详细解析旋转细节

C++AVL树的实现--详细解析旋转细节

C++_AVL树插入,查找与修改的实现(Key_Value+平衡因子+三叉链)

平衡二叉树的删除

c_cpp C ++中的AVL树实现。自平衡树

C++ 实现平衡二叉树(AVL树)(完整代码)