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