在AVL树C中插入和删除

时间:2018-07-07 05:25:47

标签: c tree binary-tree binary-search-tree avl-tree

我在插入和删除AVL树时遇到问题,在插入和从列表中删除时的旋转情况,据我测试,二叉树的一部分工作正常,但是进行了一些修改我不能保证一切都很好,我很着急,因为我必须在一天之内用C语言交付此代码

#include "avl.h"
void print_tab(int level){
  int i;
  for (i = 0; i < level; i++ )
    printf("\t");
}

void print_tree( Nodo_AVL *current, int level ){
  if ( current == NULL ) {
    print_tab(level );
    printf("~\n");
  } else {
    print_tree( current->right, level + 1 );
    print_tab(level);
    printf ("%d\n", current->key );
    print_tree( current->left, level + 1 );
  }
}

int FB(Nodo_AVL *current);
int avl_height(Nodo_AVL *current);
Nodo_AVL *rotation_LL(Nodo_AVL *current);
Nodo_AVL *rotation_RR(Nodo_AVL *current);
Nodo_AVL *rotation_LR(Nodo_AVL *current);
Nodo_AVL *rotation_RL(Nodo_AVL *current);
Nodo_AVL *findMin(Nodo_AVL *current);
Nodo_AVL *avl_delete(Nodo_AVL *current, int key);
int Balanceamento(Nodo_AVL *current);
int balancaDireita(Nodo_AVL *current);
int balancaEsquerda(Nodo_AVL *current);

Nodo_AVL *criarnodo(){
    Nodo_AVL *novo = malloc(sizeof(Nodo_AVL));
    novo->key = 0;
    novo->left = NULL;
    novo->right = NULL;
    novo->height = 0;
    return novo;
}

Nodo_AVL *avl_insert(Nodo_AVL *current, int key){
    if (current == NULL)
    {
        //printf("entrou\n");
        current = criarnodo();
        (current)->key = key;
        current->height = 0;
        return current;
    }
    else if(key < current->key){
        current->left = avl_insert((current->left), key);
        if(FB(current) == 0 || FB(current) == 1 || FB(current) == -1){

        }
        /*

- Calculate the current balancing factor after
of insertion
- If 0, -1 or +1 ... it's ok
- Calculates current height
- new height = larger between the two sides

- If FB -2 or +2 ... then unbalanced
- Calculate FB of current-> left and make the rotation you need

current = rotationLL (current);
- Calculates current height
- new height = larger between the two sides


*/
    }
    else if(key > current->key){
        current->right = avl_insert((current->right), key);
    } else {
        printf("Registro já existe\n");
        return NULL;
    }

    return current;
}

Nodo_AVL *findMin(Nodo_AVL *current){
    while (current->left != NULL){
        current = current->left;
    }
    return current;
}

int max(int a, int b)
{
    return (a > b) ? a : b;
}

Nodo_AVL *avl_delete(Nodo_AVL *current, int key){
    if (!(current))
    {
        return current;
    }
    if (key < current->key)
    {
        current->left = avl_delete(current->left, key);
    }
    else if (key > current->key)
    {
        current->right = avl_delete(current->right, key);
    } 
/*  else {
        Nodo_AVL *ocurrent = current;
        if ((current->left) && (current->right))
        {
            Nodo_AVL *parent = current->right;
            current = parent->left;
            if (current)
            {
                while(current->left){
                    parent = current;
                    current = current->left;
                }
                parent->left = current->right;
                current->right = ocurrent->right;
            }
            else
                current = parent;
            current->left = ocurrent->left;
        }
        else
            if (current->left)
            {
                current = current->left;
            }
                else {
                    current = current->right;
                }
                free(ocurrent);
            }
        return current;
*/
        else {
            if (current->left == NULL && current->right == NULL)
            {
                free(current);
                current = NULL;
            }
            if (current->left == NULL)
            {
                Nodo_AVL *temp0 = current;
                current = current->left;
                free(temp0);
            }
            if (current->right == NULL)
            {
                Nodo_AVL *temp1 = current;
                current = current->right;
                free(temp1);
            }
            else
            {
                Nodo_AVL *temp2 = findMin(current->right);
                current->key = temp2->key;
                current->right = avl_delete(current->right, temp2->key);
            }
        }
        current->height = 1 + max(avl_height(current->left), avl_height(current->right));

        int balance = Balanceamento(current);

        if(balance > 1 && Balanceamento(current->left) >= 0)
            return rotation_RR(current);

        if (balance > 1 && Balanceamento(current->right) < 0)
        {
            current->left = rotation_LL(current->left);
            return rotation_RR(current);
        }

        if (balance < -1 && Balanceamento(current->right) <=0)
            return rotation_LL(current);

        if (balance < -1 && Balanceamento(current->right) >0)
        {
            current->right = rotation_RR(current->right);
            return rotation_LL(current);
        }
        return current;
    }

void print_inOrder(Nodo_AVL *current){
    if (current != NULL)
    {
        print_inOrder(current->left);
        printf("\n%d", current->key);
        print_inOrder(current->right);
    }
}

void libera_NO(Nodo_AVL *current){
    if (current == NULL)
    {
        return;
    }
    libera_NO(current->left);
    libera_NO(current->right);
    free(current);
    current = NULL;
}

void avl_destroy(Nodo_AVL *current){
    if (current == NULL)
    {
        return;
    }
    libera_NO(current);
    //free(current);
}


Nodo_AVL *avl_search(Nodo_AVL *current, int key){
    while(current && current->key != key){
        if (key > current->key)
        {
            current = current->right;
        } else{
            current = current->left;
        }
        return current;
    }
    return NULL;
}


int avl_height(Nodo_AVL *current){
/*
    if (current == NULL) return 0;
    return current->height;
}*/
    int u, v;
    if (current == NULL) 
        return -1;
    u = avl_height(current->left);
    v = avl_height(current->right);
    if (u > v) 
        return u+1;
    else return v+1;
}

int FB(Nodo_AVL *current){
    if (current == NULL)
    {
        return 0;
    }
    //return current->left->height - current->right->height;
    return avl_height(current->left) - avl_height(current->right);
}

Nodo_AVL *rotation_LL(Nodo_AVL *current){
    Nodo_AVL *pAux;
    pAux = (current)->left;
    (current)->left = pAux->right;
    pAux->right = (current);

    return pAux;
}

Nodo_AVL * rotation_RR(Nodo_AVL *current){
    Nodo_AVL *pAux;
    pAux = (current)->right;
    (current)->right = pAux->left;
    pAux->left = (current);
    return pAux;    
}

Nodo_AVL * rotation_RL(Nodo_AVL *current){
    current = rotation_RR(current);
    current = rotation_LL(current);
    return current;
}

Nodo_AVL * rotation_LR(Nodo_AVL *current){
    current = rotation_LL(current);
    current = rotation_RR(current);
    return current;
}

int balancaEsquerda(Nodo_AVL *current){
    int fbe = FB (current->left);
    if (fbe > 0)
    {
        rotation_LL(current);
        return 1;
    }
    else if (fbe < 0)
    {
        rotation_RR(current->left);
        rotation_LL(current);
        return 1;
    }
    return 0;
}

int balancaDireita(Nodo_AVL *current){
    int fbd = FB(current->right);
    if (fbd < 0)
    {
        rotation_RR(current);
        return 1;
    }
    else if (fbd > 0)
    {
        rotation_LL(current->right);
        rotation_RR(current);
        return 1;
    }
    return 0;
}

int Balanceamento(Nodo_AVL *current){
    int fb = FB(current);
    if (fb > 1)
    {
        return balancaEsquerda(current);
    }
    else if (fb < -1)
    {
        return balancaDireita(current);
    }

    return 0;
}

0 个答案:

没有答案