繁体   English   中英

AVL 树旋转问题

[英]AVL tree Rotation problems

我一直面临着 AVL 树实现的一个非常奇怪的问题。 鉴于下面的代码,我只能在没有正确旋转的情况下运行它,因为如果我这样做,我就会崩溃。 我已经尝试过调试、删除文件和重建项目,然后重建,这些都没有奏效。

事先,如果代码有点难以理解,我深表歉意,我是巴西人,变量名主要是葡萄牙语,如果证明这对帮助解决问题有问题,我会将变量名更改为英文。

avl.h文件:

#include <stdio.h>
#include <stdlib.h>

typedef struct avl{
    int elemento;
    struct avl *esq;
    struct avl *dir;
    int altura;
}avl;

avl *novo_no(int);
avl *rotacao_dir(avl *);
avl *rotacao_esq(avl *);
avl *insercao_avl(avl *, int);
int calcula_fb(avl *);
int max(int, int);
int get_altura(avl *);
void in_order(avl *);

avl.c文件:

#include "avl_tree.h"

//creates a new node with the given integer
avl *novo_no(int elemento){
    avl *novo = (avl *)malloc(sizeof(avl));
    if(novo){
        novo->elemento = elemento;
        novo->dir = NULL;
        novo->esq = NULL;
        novo->altura = 1;
        return novo;
    }else
        exit(1);
}

//right rotation
avl *rotacao_dir(avl *arv){

    avl *filho_esq = arv->esq;
    avl *subarvore_dir = filho_esq->dir;

    filho_esq->dir = arv;
    arv->esq = subarvore_dir;

    //updates the height

    arv->altura = max(get_altura(arv->esq), get_altura(arv->dir)) + 1;
    filho_esq->altura = max(get_altura(filho_esq->esq), get_altura(filho_esq->dir)) + 1;
    //printf("Altura de [%d]: %d\n\n", filho_esq->elemento, filho_esq->altura); //debug print of the node and it's height

    return filho_esq;
}

//left rotation
avl *rotacao_esq(avl *arv){
    avl *filho_dir = arv->dir;
    avl *subarvore_esq = filho_dir->esq;

    filho_dir->esq = arv;
    arv->dir = subarvore_esq;

    //updates the height

    arv->altura = max(get_altura(arv->esq), get_altura(arv->dir)) + 1;
    filho_dir->altura = max(get_altura(filho_dir->esq), get_altura(filho_dir->dir)) + 1;
    printf("Altura de [%d]: %d", filho_dir->elemento, filho_dir->altura);

    return filho_dir;
}

//insertion
avl *insercao_avl(avl *arv, int elemento){

    /*1. BST normal insertion*/

    if(arv == NULL) return novo_no(elemento);

    avl *aux = arv;
    if(elemento <= aux->elemento)
        aux->esq = insercao_avl(aux->esq, elemento);
    else
        aux->dir = insercao_avl(aux->dir, elemento);

    //Inicia os testes para as rotacoes

    /*2. updates height */
    arv->altura = max(get_altura(arv->esq), get_altura(arv->dir)) + 1;

    /*3. get the balance*/
    int fb = calcula_fb(arv);
    printf("FB do no[%d] = %d\n",arv->elemento, fb);

    //If unbalanced node, 1 of the 4 following cases will apply:

    //3.1 esq->esq
    if (fb > 1 && elemento < arv->esq->elemento)
        return rotacao_dir(arv);

    //3.2 dir->dir
    else if (fb < -1 && elemento > arv->dir->elemento)
        return rotacao_dir(arv);

    //3.3 esq->dir
    else if (fb > 1 && elemento > arv->esq->elemento){
        arv->esq =  rotacao_dir(arv->esq);
        return rotacao_dir(arv);
    }

    //3.4 dir->esq
    else if (fb < -1 && elemento < arv->dir->elemento){
        arv->dir = rotacao_dir(arv->dir);
        return rotacao_dir(arv);
    }

    /*4. Returns node */
    return arv;
}

//gets the balancing factor of a node
int calcula_fb(avl *arv){
    if(arv == NULL) return 0;
    else return(get_altura(arv->esq) - get_altura(arv->dir));
}


//get max between 2 values
int max(int a, int b){
    return((a > b) ? a : b);
}

//get a node's height
int get_altura(avl *arv){
    if(arv == NULL) return 0;
    else return arv->altura;
}

// in-order travel of the tree
void in_order(avl *arv){
    if(arv == NULL) // se arvore vazia então finaliza
        return;

    in_order(arv->esq); // chamada recursiva para a subarvore esquerda
    printf("[ %2d ] ", arv->elemento); // visita a raiz
    in_order(arv->dir); // chamada recursiva para a subarvore direita
}

main.c文件:

#include <stdio.h>
#include <stdlib.h>
#include "avl_tree.h"

int main(){

    avl *raiz;
    int i;
    for(i = 0; i < 10; i++)
        raiz = insercao_avl(raiz, i);

    in_order(raiz);


    return 0;
}

如您所见,我的左右旋转函数(分别为rotaciona_dirrotaciona_esq )基本上是镜像,所以让我觉得正确的一个不起作用。 我尝试了不同的调用,现在我只是使用for循环进行测试。如果我让我的输入减少,一切正常,但是一旦我需要调用rotaciona_dir函数,程序就会崩溃。

关于 IDE/编译器,我在 Ubuntu 16.04 LTS 系统中使用 Code-Blocks IDE 13.12。

此外,欢迎任何代码改进或一般编程技巧。 我自己并不是一个 C 程序员(Python 是我的主要语言),所以这个问题的答案可能非常简单,我只是不明白。

所以看起来我使用自动完成有点太多了。 我的案例都没有调用rotacao_esq ,我的左旋转函数,这导致代码出现故障。 学过的知识。 将此问题标记为已解决。 感谢所有帮助并特别感谢@IanAbbott 指出新手错误的人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM