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

版本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;
} 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值