我在插入和删除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;
}