Prévia do material em texto
Algoritmos e Estrutura de Dados III
Lista de exercício 2
Nome: Guilherme Vemado Nº: 201010347
Árvore Binária completamente balanceada
Árvore Binária balanceada
Árvore Binária cheia
a)
b) Os passos realizados na primeira fase
a) Inserção da chave 10,11 (Rotação Dupla):
b) Inserção da chave 6 (Rotação Simples):
c) Inserção da chave 1 (Árvore permanece balanceada):
d) Inserção da chave 2, 3, 7, 9, 12:
Função implementada em C:
void rotacaoEsquerda(Apontador *p)
{
if((*p)==NULL || (*p)->Dir==NULL) /*Verifica se o no passado, ou seu filho a direita e nulo*/
{
printf("Rotacao impossivel de ser realizada!\n");
}
else
{
Apontador pfilhoDir = (*p)->Dir;
(*p)->Dir = pfilhoDir->Esq;
pfilhoDir->Esq = (*p);
(*p) = pfilhoDir;
}
}
Função Implementada em C:
void rotacaoDireita(Apontador *p)
{
if((*p)==NULL || (*p)->Esq==NULL) /*Verifica se o no passado, ou seu filho a esquerda e nulo*/
{
printf("Rotacao impossivel de ser realizada!\n");
}
else
{
Apontador pfilhoEsq = (*p)->Esq;
(*p)->Esq = pfilhoEsq->Dir;
pfilhoEsq->Dir = (*p);
(*p) = pfilhoEsq;
}
}
Função Implementada em C:
void rotacaoEsqDir(Apontador *pAvo)
{
if((*pAvo)->Esq==NULL || (*pAvo)->Esq->Dir==NULL || (*pAvo)==NULL) /*Verifica se o no avo, ou seu filho a esquerda, ou seu filho a direita do filho a esquerda e nulo*/
{
printf("Rotacao Impossivel de ser realizada!\n");
}
else
{
rotacaoEsquerda(&(*pAvo)->Esq); /*E executada uma rotacao a esquerda com o no pai a esquerda*/
rotacaoDireita(&(*pAvo));/*E executada uma rotacao a direita com o no avo atual*/
}
}
Implementação para Teste:
#include <stdlib.h>
typedef int TipoChave;
typedef struct Registro {
TipoChave Chave;
} Registro;
typedef struct No * Apontador;
typedef struct No {
Registro Reg;
Apontador Esq, Dir;
} No;
typedef Apontador TipoDicionario;
void rotacaoEsquerda(Apontador *p)
{
if((*p)==NULL || (*p)->Dir==NULL) /*Verifica se o no passado, ou seu filho a direita e nulo*/
{
printf("Rotacao impossivel de ser realizada!\n");
}
else
{
Apontador pfilhoDir = (*p)->Dir;
(*p)->Dir = pfilhoDir->Esq;
pfilhoDir->Esq = (*p);
(*p) = pfilhoDir;
}
}
void rotacaoDireita(Apontador *p)
{
if((*p)==NULL || (*p)->Esq==NULL) /*Verifica se o no passado, ou seu filho a esquerda e nulo*/
{
printf("Rotacao impossivel de ser realizada!\n");
}
else
{
Apontador pfilhoEsq = (*p)->Esq;
(*p)->Esq = pfilhoEsq->Dir;
pfilhoEsq->Dir = (*p);
(*p) = pfilhoEsq;
}
}
void rotacaoEsqDir(Apontador *pAvo)
{
if((*pAvo)->Esq==NULL || (*pAvo)->Esq->Dir==NULL || (*pAvo)==NULL) /*Verifica se o no avo, ou seu filho a esquerda, ou seu filho a direita do filho a esquerda e nulo*/
{
printf("Rotacao Impossivel de ser realizada!\n");
}
else
{
rotacaoEsquerda(&(*pAvo)->Esq); /*E executada uma rotacao a esquerda com o no pai a esquerda*/
rotacaoDireita(&(*pAvo));/*E executada uma rotacao a direita com o no avo atual*/
}
}
void ListarTabulado(No *p,int nivel)
{
int i;
nivel++;
if (p != NULL)
{
for(i=1;i<nivel;i++)
{
printf(" ");
}
printf("%d\n",p->Reg.Chave);
ListarTabulado(p->Esq,nivel);
ListarTabulado(p->Dir,nivel);
}else printf("---\n");
}
int Insere(Registro x, Apontador *p)
{
if (*p == NULL)
{ *p = (Apontador)malloc(sizeof(No));
(*p)->Reg = x; (*p)->Esq = NULL; (*p)->Dir = NULL;
return 0;
}else
if (x.Chave < (*p)->Reg.Chave)
{
if( Insere(x, &(*p)->Esq)==-1 ) return -1;
else return 0;
}else
if (x.Chave > (*p)->Reg.Chave)
{
if( Insere(x, &(*p)->Dir)==-1 ) return -1;
else return 0;
}
else
{
printf("Erro : Registro ja existe na arvore\n");
return -1;
}
}
int main()
{
No *Dicionario=NULL; //Declara Dicionario
Registro X; //Declara tipo registro
X.Chave=500; //Passa chave igual a 500 para o registro X
Insere(X,&Dicionario); // Insere Registro X na arvore binaria
X.Chave=400; //Passa chave igual a 400 para o registro X
Insere(X,&Dicionario); // Insere Registro X na arvore binaria
X.Chave=450; //Passa chave igual a 450 para o registro X
Insere(X,&Dicionario); // Insere Registro X na arvore binaria
printf("Arvore antes da rotacao Esquerda-Direita:\n");
ListarTabulado(Dicionario,0); //Exibe arvore atraves do metodo por tabulacao
rotacaoEsqDir(&Dicionario); //Faz rotacao Esquerda Direita atraves das funções de rotacao ja criada
printf("Arvore depois da rotacao Esquerda-Direita:\n");
ListarTabulado(Dicionario,0); //Exibe arvore atraves do metodo por tabulacao, mostrando o sucesso da rotacao
system("pause");
return 0;
}
Algoritmo DSW
Função DSWBalancingAlgorithm:
O primeiro passo é transformar toda a árvore em uma espinha dorsal através das rotações para a direita, com os nós filhos a esquerda. No final da operação, a árvore fica com a sua altura igual ao número de nós. Após tal transformação, passaremos para o segundo passo, onde algoritmo executa i rotações a esquerda, sendo i igual a parte inteira da divisão do número de nós por dois. O algoritmo pega de dois em dois nós a direita, para poder fazer as rotações. Após o término da primeira sequência de rotações, o algoritmo divide i por dois, e pega somente a sua parte inteira, para assim fazer uma nova i rotações à esquerda. Essa operação é executada até que a parte inteira de i for menor um. No final teremos uma árvore balanceada.
Função LeftRotate:
O algoritmo modifica somente os ponteiros para a esquerda e direita dos nó pai e do nó filho, e faz com que o nó a esquerda do nó pai seja apontado para o nó a sua direita. Depois é efetuada a troca dos valores contidos, para que a árvore fique regularizada. A árvore a esquerda do nó pai permanece a sua esquerda, o nó a direita do nó pai passa a ser o nó a esquerda do nó filho e o nó a direita do nó filho permanece sendo o nó a direita.
Função RightRotate:
Assim como no LeftRotate, o algoritmo modifica somente os ponteiros para a esquerda e direita dos nó pai e do nó filho, e faz com que o nó a direita do nó pai seja apontado para o nó a sua esquerda. Depois é efetuada a troca dos valores contidos, para que a árvore fique regularizada. A arvore a esquerda do nó filho continua sendo o seu nó a esquerda, o nó a direita do nó filho passa a ser o nó a esquerda do nó filho, o nó a direita do nó pai continua sendo o seu nó filho. Os valores contidos nos nós são trocados para que a árvore permaneça regularizada.