#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;
}

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。