Академический Документы
Профессиональный Документы
Культура Документы
com balanceamento
Algoritmos e Estruturas de Dados II
rvores binrias de pesquisa
Pior caso para uma busca O(n)
1
Ordem de insero:
132456
3
2 4
2
rvore completamente balanceada
Ns folha (externos) aparecem em no mximo
dois nveis diferentes
3
rvore completamente balanceada
Para inserir a chave 1 na rvore esquerda e
manter a rvore completamente balanceada
precisamos movimentar todos os ns
4
rvores quase balanceadas
Objetivo:
Funes para pesquisar, inserir e retirar eficientes
O(lg(n))
5
rvores quase balanceadas
Vrias formas de definir e construir uma rvore
quase balanceada
Exemplos de restries aplicadas a rvores para
faz-las quase balanceadas
Fazer que todas as folhas aparecem no mesmo nvel
Restringir a diferena entre as alturas das subrvores
de cada n
Minimizar o comprimento do caminho interno da rvore
8=0+1+1+2+2+2
6
rvores SBB
Uma rvore SBB uma rvore binria com
apontadores verticais e horizontais, tal que:
Todos os caminhos da raiz at cada n externo
possuem o mesmo nmero de apontadores verticais
No podem existir dois apontadores horizontais
sucessivos
7
rvores SBB estrutura
#define SBB_VERTICAL 0
#define SBB_HORIZONTAL 1
struct sbb {
struct registro reg;
struct sbb *esq;
struct sbb *dir;
int esqtipo;
int dirtipo;
}
8
Pesquisa em rvore SBB
Idntica pesquisa em uma rvore de busca
binria no balanceada
Ignoramos a direo dos apontadores
9
Insero numa rvore SBB
A chave a ser inserida sempre inserida aps o
apontador vertical mais baixo na rvore
Dependendo da situao anterior insero
podem aparecer dois apontadores horizontais
Insero do 4, 6, 8, 11?
10
Transformaes para manter
propriedadas da rvore SBB
Mtodos para reorganizar casos onde aparecem
dois ponteiros horizontais consecutivos
Esquerda-esquerda (e direita-direita)
Esquerda-direita (e direita-esquerda)
11
Transformaes para manter
propriedadas da rvore SBB - cdigo
void ee(struct sbb **ptr) {
struct sbb *no = *ptr;
struct sbb *esq = no->esq;
no->esq = esq->dir;
esq->dir = no;
esq->esqtipo = SBB_VERTICAL;
no->esqtipo = SBB_VERTICAL;
*ptr = esq;
}
ptr
esq no
12
Transformaes para manter
propriedadas da rvore SBB - cdigo
void ed(struct sbb **ptr) {
struct sbb *no = *ptr;
struct sbb *esq = no->esq;
struct sbb *dir = esq->dir;
esq->dir = dir->esq;
no->esq = dir->dir;
dir->esq = esq;
dir->dir = no;
esq->dirtipo = SBB_VERTICAL;
no->esqtipo = SBB_VERTICAL;
*ptr = dir;
} ptr
esq dir no
13
Exemplo de insero em rvore SBB
Inserir chaves 7, 10, 5, 2, 4, 9, 3, 6, 5.5
14
Insero em rvores SBB
void iinsere(struct registro reg, struct sbb **ptr,
int *incli, int *fim) {
if(*ptr == NULL) {
iinsere_aqui(reg, ptr, incli, fim);
} else if(reg.chave < *ptr->reg.chave) {
iinsere(reg, &(*ptr->esq), &(*ptr->esqtipo), fim);
if(*fim) return;
if(*ptr->esqtipo == SBB_VERTICAL) {
*fim = TRUE;
} else if(*ptr->esq->esqtipo == SBB_HORIZONTAL) {
ee(ptr); *incli = SBB_HORIZONTAL;
} else if(*ptr->esq->dirtipo == SBB_HORIZONTAL) {
ed(ptr); *incli = SBB_HORIZONTAL;
}
} else if(reg.chave > (*ptr)->reg.chave) {
/* igual acima, s inverte o lado */
} else {
printf(erro: chave j est na rvore.\n);
*fim = TRUE; } }
15
Insero em rvores SBB
void iinsere_aqui(struct registro reg, struct sbb **ptr,
int *incli, int *fim) {
struct sbb *no = malloc(sizeof(struct sbb));
if(!no) { perror(NULL); exit(EXIT_FAILURE); }
no->reg = reg;
no->esq = NULL;
no->dir = NULL;
no->esqtipo = SBB_VERTICAL;
no->dirtipo = SBB_VERTICAL;
*ptr = no;
*incli = SBB_HORIZONTAL;
*fim = FALSE;
}
16
Insero em rvores SBB
void insere(struct registro reg, struct sbb **raiz)
{
int fim = FALSE;
int inclinacao = SBB_VERTICAL;
iinsere(reg, raiz, &inclinacao, &fim);
}
17
Retirada numa rvore SBB
Usaremos trs procedimentos auxiliares
EsqCurto: chamado quando o n retirado esquerda
e diminui a altura da rvore
DirCurto: chamado quando um n retirado direita e
diminui a altura da rvore
Antecessor: chamado quando um n possui dois filhos
18
Retirada em rvore SBB exemplos
Retirando 7, 4 e 9:
19
Retirada em rvore SBB exemplos
20
Retirada em rvore SBB exemplos
21
Retirada em rvore SBB exemplos
22
Retirada em rvore SBB exemplos
23
Retirada de rvore SBB cdigo
void iretira(struct registro reg, struct sbb **ptr, int *fim) {
if(*ptr == NULL) { *fim = TRUE; return; }
if(reg.chave < *ptr->reg.chave) {
iretira(reg, &(*ptr->esq), fim);
if(!(*fim)) { EsqCurto(ptr, fim);
} else if(reg.chave > *ptr->reg.chave) {
/* igual acima, s inverte o lado. */
} else { /* achou o registro: */
*fim = FALSE;
struct sbb *no = *ptr;
if(no->dir == NULL) {
*ptr = no->esq;
free(no);
if(*ptr != NULL) { *fim = TRUE; }
} else if(no->esq == NULL) { /* igual acima. */ }
} else {
antecessor(ptr, &(*ptr->esq), fim);
if(!(*fim)) EsqCurto(ptr, fim);
}
}}
24
Retirada de rvore SBB cdigo
void EsqCurto(struct sbb **ptr, int *fim) {
if(*ptr->esqtipo == SBB_HORIZONTAL) {
*ptr->esqtipo = SBB_VERTICAL; *fim = TRUE;
} else if(*ptr->dirtipo == SBB_HORIZONTAL) {
struct sbb *dir = *ptr->dir;
*ptr->dir = dir->esq;
dir->esq = *ptr;
*ptr = dir;
if(*ptr->esq->dir->esqtipo == SBB_HORIZONTAL) {
de(&(*ptr->esq)); *ptr->esqtipo = SBB_HORIZONTAL;
} else if(*ptr->esq->dir->dirtipo == SBB_HORIZONTAL) {
dd(&(*ptr->esq)); *ptr->esqtipo = SBB_HORIZONTAL;
}
*fim = TRUE;
} else {
*ptr->dirtipo = SBB_HORIZONTAL;
if(*ptr->dir->esqtipo == SBB_HORIZONTAL) {
de(ptr); *fim = TRUE;
} else if(/* checa outro lado */) { ... }
}}}
25
SBBs anlise
Dois tipos de altura
Altura vertical h: conta o nmero de apontadores
verticais da raiz at as folhas
Altura k: o nmero de ponteiros atravessados
(comparaes realizadas) da raiz at uma folha
26
SBBs anlise
Bayer (1972) mostrou que
lg( n + 1) k 2 lg( n + 2) 2
27
Exerccios
Desenhe a rvore SBB resultante da insero
das chaves Q U E S T A O F C I L em uma
rvore vazia.
Qual o maior nmero de ns que pode ser
armazenado numa rvore SBB com altura h?
D a lista de inseres que gera a rvore SBB
abaixo:
4 6
2 5 8
28