(转)AVL树的插入_删除操作

来源:互联网 发布:中国未来 知乎 编辑:程序博客网 时间:2024/06/06 03:17

版本1:

 

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <assert.h>typedef struct node node;struct node{  node* parent;  node* left;  node* right;  int   balance;  //左右子树高度之差  int   key;};extern void traverseAVL1(node* root); //中序遍历, 下面定义extern void traverseAVL2(node* root); //前序遍历, 下面定义int searchNode(int key, node* root, node** parent) //按key查找结点{  node* temp;  assert(root != NULL);  temp = root;  *parent = root->parent;  while (temp !=NULL)  {    if (temp->key == key)      return 1;    else    {       *parent = temp;      if (temp->key > key)        temp = temp->left;      else         temp = temp->right;    }  }  return 0;}node* minNode(node* root) //树root的最小结点{  if (root == NULL)    return NULL;  while (root->left != NULL)    root = root->left;  return root;}node* maxNode(node* root) //树root的最大结点{  if (root == NULL)    return NULL;  while (root->right != NULL)    root = root->right;  return root;}node* preNode(node* target) //求前驱结点{  if (target == NULL)    return NULL;  if (target->left != NULL)    return maxNode(target->left);  else    while ((target->parent!=NULL) && (target!=target->parent->right))      target = target->parent;  return target->parent;}node* nextNode(node* target) //求后继结点{  if (target == NULL)    return NULL;  if (target->right != NULL)    return minNode(target->right);  else    while ((target->parent!=NULL) && (target!=target->parent->left))      target = target->parent;  return target->parent;}node* adjustAVL(node* root, node* parent, node* child){  node *cur;  assert((parent != NULL)&&(child != NULL));  switch (parent->balance)  {  case 2:    if (child->balance == -1)//LR型    {      cur = child->right;      cur->parent = parent->parent;      child->right = cur->left;      if (cur->left != NULL)        cur->left->parent = child;      parent->left = cur->right;      if (cur->right != NULL)        cur->right->parent = parent;      cur->left = child;      child->parent = cur;      cur->right = parent;      if (parent->parent != NULL)        if (parent->parent->left == parent)          parent->parent->left = cur;        else parent->parent->right = cur;      else        root = cur;      parent->parent = cur;      if (cur->balance == 0)      {        parent->balance = 0;        child->balance = 0;      }      else if (cur->balance == -1)      {        parent->balance = 0;        child->balance = 1;      }      else      {        parent->balance = -1;        child->balance = 0;      }      cur->balance = 0;    }    else //LL型    {      child->parent = parent->parent;      parent->left = child->right;      if (child->right != NULL)        child->right->parent = parent;      child->right = parent;      if (parent->parent != NULL)        if (parent->parent->left == parent)          parent->parent->left = child;        else parent->parent->right = child;      else        root = child;      parent->parent = child;      if (child->balance == 1) //插入时      {        child->balance = 0;        parent->balance = 0;      }      else //删除时      {        child->balance = -1;        parent->balance = 1;      }    }   break;     case -2:    if (child->balance == 1) //RL型    {      cur = child->left;      cur->parent = parent->parent;      child->left = cur->right;      if (cur->right != NULL)        cur->right->parent = child;      parent->right = cur->left;      if (cur->left != NULL)        cur->left->parent = parent;      cur->left = parent;      cur->right = child;      child->parent = cur;      if (parent->parent != NULL)        if (parent->parent->left == parent)          parent->parent->left = cur;        else parent->parent->right = cur;      else        root = cur;      parent->parent = cur;      if (cur->balance == 0)      {        parent->balance = 0;        child->balance = 0;      }      else if (cur->balance == 1)      {        parent->balance = 0;        child->balance = -1;      }      else      {        parent->balance = 1;        child->balance = 0;      }      cur->balance = 0;    }    else  //RR型    {      child->parent = parent->parent;      parent->right = child->left;      if (child->left != NULL)        child->left->parent = parent;      child->left = parent;      if (parent->parent != NULL)        if (parent->parent->left == parent)          parent->parent->left = child;        else parent->parent->right = child;      else        root = child;      parent->parent = child;      if (child->balance == -1) //插入时      {        child->balance = 0;        parent->balance = 0;      }      else //删除时      {        child->balance = 1;        parent->balance = -1;      }    }    break;  }  return root;}node* insertNode(int key, node* root){  node *parent, *cur, *child;  assert (root != NULL);  if (searchNode(key, root, &parent)) //结点已存在    return root;  else  {    cur = (node*)malloc(sizeof(node));    cur->parent = parent;    cur->key = key;    cur->left = NULL;    cur->right = NULL;    cur->balance = 0;    if (key<parent->key)    {      parent->left = cur;      child = parent->left;    }    else    {      parent->right = cur;      child = parent->right;    }        while ((parent != NULL)) //查找需要调整的最小子树    {      if (child == parent->left)        if (parent->balance == -1)        {          parent->balance = 0;          return root;        }        else if (parent->balance == 1)        {          parent->balance = 2;          break;        }        else        {          parent->balance = 1;          child = parent;          parent = parent->parent;        }      else if (parent->balance == 1)      {        parent->balance = 0;        return root;      }      else if (parent->balance == -1)      {        parent->balance = -2;        break;      }      else       {        parent->balance = -1;        child = parent;        parent = parent->parent;      }    }        if (parent == NULL)      return root;    return adjustAVL(root, parent, child);  }}node* deleteNode(int key, node* root){  node *dNode, *parent, *child, *tp;  int temp, tc;  assert(root!=NULL);  if (!searchNode(key, root, &parent))    return root;  else  {    if (parent == NULL)      dNode = root;    else if ((parent->left!=NULL)&&(parent->left->key==key))      dNode = parent->left;    else dNode = parent->right;    child = dNode;    while ((child->left!=NULL)||(child->right!=NULL)) //确定需要删除的结点    {      if (child->balance == 1)        child = preNode(dNode);      else child = nextNode(dNode);      temp = child->key;      child->key = dNode->key;      dNode->key = temp;      dNode = child;    }       child = dNode;    parent = dNode->parent;          while ((parent != NULL)) //查找需要调整的最小子树    {      if (child == parent->left)        if (parent->balance == 1)        {          parent->balance = 0;          child = parent;          parent = parent->parent;        }        else if (parent->balance == -1)        {          parent->balance = -2;          child = parent->right;          temp = parent->right->balance;//临时变量保存          tp = parent->parent;//临时变量保存          if (tp != NULL)            if (parent == tp->left)              tc = 1;            else tc = -1;          else tc = 0;                    root = adjustAVL(root, parent, child);                   if (temp == 0)            break;          else          {            if (tc == 1)              child = tp->left;            else if (tc == -1)              child = tp->right;            parent = tp;          }        }        else        {          parent->balance = -1;          break;        }      else if (parent->balance == -1)      {        parent->balance = 0;        child = parent;        parent = parent->parent;      }      else if (parent->balance == 1)      {        parent->balance = 2;        child = parent->left;        temp = parent->left->balance;//临时变量保存        tp = parent->parent;//临时变量保存        if (tp != NULL)          if (parent == tp->left)            tc = 1;          else tc = -1;        else tc = 0;                root = adjustAVL(root, parent, child);                if (temp == 0)          break;        else        {          if (tc == 1)            child = tp->left;          else if (tc == -1)            child = tp->right;          parent = tp;        }      }      else      {        parent->balance = 1;        break;      }    }        if (dNode->parent != NULL)      if (dNode == dNode->parent->left)        dNode->parent->left = NULL;      else dNode->parent->right = NULL;    free(dNode);    if (root == dNode)      root = NULL; //root被删除, 避免野指针    dNode = NULL;        return root;  }}node* createAVL(int *data, int size){  int i, j;  node *root;  if (size<1)    return NULL;  root = (node*)malloc(sizeof(node));  root->parent = NULL;  root->left = NULL;  root->right = NULL;  root->key = data[0];  root->balance = 0;    for(i=1;i<size;i++)    root = insertNode(data[i], root);  return root;}void destroyAVL(node* root){  if (root != NULL)  {    destroyAVL(root->left);    destroyAVL(root->right);    free(root);    root=NULL;  }  }void traverseAVL1(node* root) //中序遍历{  if (root != NULL)  {    traverseAVL1(root->left);    printf("%d, %d\n", root->key, root->balance);    traverseAVL1(root->right);  }}void traverseAVL2(node* root) //先序遍历{  if (root != NULL)  {    printf("%d, %d\n", root->key, root->balance);    traverseAVL2(root->left);    traverseAVL2(root->right);  }}int main(int argc, char *argv[]){  int data[] = {1, 5, 7, 4, 3, 2, 11, 9, 10};  node* root;  root = createAVL(data, sizeof(data)/sizeof(data[0]));  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);    root = deleteNode(5, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  root = deleteNode(3, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  root = deleteNode(1, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  root = deleteNode(7, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  root = deleteNode(4, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  root = deleteNode(2, root);  printf("++++++++++++++++++++++++++++\n");  traverseAVL1(root);  printf("\n");  traverseAVL2(root);  destroyAVL(root);}


 

版本2:

#include <stdio .h>#include <stdbool .h>#include <stdlib .h> char chos;int input;bool unbalanced = false;struct node{    int data;    int bf;    node *lchild;    node *rchild;};typedef struct node *BST;BST R = NULL; void Chose(){    printf("i) Insert a point\n"           "d) Delete a point\n"           "e) exit\n"           "Input your choose:");    scanf(" %c", &chos);}int Height(BST T){     /*返回当前节点的高度*/    if(T == NULL)        return -1;    else        return T->bf;}int Max(int A, int B){    return ((A > B) ? A:B);}BST SingleRotateWithRight(BST K2){          /*RR型旋转*/    BST K1;    K1 = K2->rchild;    K2->rchild = K1->lchild;    K1->lchild = K2;    K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1;    K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1;    return K1;}BST SingleRotateWithLeft(BST K2){           /*LL型旋转*/    BST K1;    K1 = K2->lchild;    K2->lchild = K1->rchild;    K1->rchild = K2;    K2->bf = Max(Height(K2->lchild), Height(K2->rchild)) + 1;    K1->bf = Max(Height(K1->lchild), Height(K1->rchild)) + 1;    return K1;}BST DoubleRotateWithLeft(BST K3){           /*LR = RR(K3->lchild) + LL(K3)*/    K3->lchild = SingleRotateWithRight(K3->lchild);    return SingleRotateWithLeft(K3);}BST DoubleRotateWithRight(BST K3){          /*LL = LL(K3->lchild) + RR(K3)*/    K3->rchild = SingleRotateWithLeft(K3->rchild);    return SingleRotateWithRight(K3);}void OUT(BST T){                /*树的输出递归函数*/    if(T->lchild){        printf("Left\t%d\t[parent:%d]\n", T->lchild->data, T->data);        OUT(T->lchild);    }    if(T->rchild){        printf("Right\t%d\t[parent:%d]\n", T->rchild->data, T->data);        OUT(T->rchild);    }}BST Rotate(BST T){              /*对于单个节点进行的AVL调整*/    if(Height(T->lchild) - Height(T->rchild) == 2){        if(Height(T->lchild->lchild) >= Height(T->lchild->rchild)){            T = SingleRotateWithLeft(T);        }        else{            T = DoubleRotateWithLeft(T);        }    }    if(Height(T->rchild) - Height(T->lchild) ==2){        if(Height(T->rchild->rchild) >= Height(T->rchild->lchild)){            T = SingleRotateWithRight(T);        }        else{            T = DoubleRotateWithRight(T);        }    }    return T;}BST AVLInsert(BST T){           /*AVL数的插入操作*/    if(T == NULL){        T = (BST)malloc(sizeof(struct node));        T->data = input;        T->lchild = T->rchild = NULL;        T->bf = 0;    }    else if(input < T->data){        T->lchild = AVLInsert(T->lchild);        if(Height(T->lchild) - Height(T->rchild) == 2){            if(input < T->lchild->data){                T = SingleRotateWithLeft(T);            /*LL旋转*/            }            else{                T = DoubleRotateWithLeft(T);            /*LR旋转*/            }        }    }    else if(input > T->data){        T->rchild = AVLInsert(T->rchild);        if(Height(T->rchild) - Height(T->lchild) == 2){            if(input > T->rchild->data){                T = SingleRotateWithRight(T);           /*RR旋转*/            }            else{                T = DoubleRotateWithRight(T);           /*RL旋转*/            }        }    }    T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;    return T;}void Output(BST T){    if(T == NULL){        printf("None\n");    }    else{        printf("%d\troot\n", T->data);        OUT(T);    }}void Insert(){    printf("\nInput the point your want to Insert: ");    scanf("%d", &input);    R = AVLInsert(R);    Output(R);}BST AVLDelete(BST T, int key){    if(T == NULL)        return NULL;    if(key == T->data){        if(T->rchild == NULL){          /*如果T得右儿子为空则直接删除*/            BST temp = T;            T = T->lchild;            free(temp);        }        else{                           /*否则找到T->rchild的最左儿子代替T*/            BST temp = T->rchild;            while(temp->lchild != NULL){                temp = temp->lchild;            }            T->data = temp->data;            T->rchild = AVLDelete(T->rchild, temp->data);      /*对于替代后的T及其各个子节点进行一些列调整,正到再次递归到T->rchild的最左儿子,删除它*/            T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;        }        return T;    }    else if(key < T->data){        T->lchild = AVLDelete(T->lchild, key);    }    else{        T->rchild = AVLDelete(T->rchild, key);    }    T->bf = Max(Height(T->lchild), Height(T->rchild)) + 1;    if(T->lchild != NULL){        T->lchild = Rotate(T->lchild);    }    if(T->rchild != NULL){        T->rchild = Rotate(T->rchild);    }    T = Rotate(T);    return T;}void Delete(){    printf("\nInput the point you want to Delete: ");    scanf("%d", &input);    R = AVLDelete(R, input);    Output(R);}int main(){    while(1){        Chose();        switch(chos){            case 'i':                Insert();                break;            case 'd':                Delete();                break;            case 'e':                exit(0);        }    }    return 0;} 


 

原创粉丝点击