Você está na página 1de 59

AULA 19

ESTRUTURA DE DADOS
rvores N-rias
Norton T. Roman & Luciano A. Digiampietri

rvores N-rias
Algumas vezes, a rvore binria no a melhor escolha
Se lidar com grandes volumes de dados, sua
profundidade cresce
Dependendo da modelagem do problema, cada n
precisa ter um nmero variado de filhos, de 0 a n,
com n > 2

rvores N-rias
Que fazer?

rvores N-rias
Que fazer?
Se precisamos de mais filhos, mais filhos o que
teremos rvore n-ria

rvores N-rias
Que fazer?
Se precisamos de mais filhos, mais filhos o que
teremos rvore n-ria
Definio 1: Uma rvore n-ria uma rvore em que
cada n pode ter at n filhos

rvores N-rias
Que fazer?
Se precisamos de mais filhos, mais filhos o que
teremos rvore n-ria
Definio 1: Uma rvore n-ria uma rvore em que
cada n pode ter at n filhos
Definio 2: Uma rvore n-ria uma rvore em que
cada n pode ter um nmero arbitrrio de filhos

rvores N-rias
Trata-se ento de uma generalizao das rvores
binrias

rvores N-rias
Trata-se ento de uma generalizao das rvores
binrias
E qual definio usar?

rvores N-rias
Trata-se ento de uma generalizao das rvores
binrias
E qual definio usar?
A que melhor se adaptar ao problema modelado

rvores N-rias
Trata-se ento de uma generalizao das rvores
binrias
E qual definio usar?
A que melhor se adaptar ao problema modelado
Nessa aula, seguiremos o modelo mais geral,
seguindo a Definio 2

rvores N-rias
Suponha que queremos
modelar a seguinte
rvore:

8
15
20

10

23
28

2
36

rvores N-rias
Suponha que queremos
modelar a seguinte
rvore:
Como seria a
representao do n?

8
15
20

10

23
28

2
36

rvores N-rias
8

Antes, repare que no h


ordem nos ns...

15
20

10

23
28

2
36

rvores N-rias
8

Antes, repare que no h


ordem nos ns...
Mas e como fica sua
representao?

15
20

10

23
28

2
36

rvores N-rias
8

Antes, repare que no h


ordem nos ns...
Mas e como fica sua
representao?
Uma possibilidade :

15
20

10

23
28

2
36

chave
filho irmo

rvores N-rias
Ento, nossa rvore fica...
8
15
20

10

23
28

2
36

rvores N-rias
Ento, nossa rvore fica...
3000

2200 null
2200

15
20

10

23
28

2
36

3120

1120

15

23

1344 3120

null 1120

112 null

1344

124

112

4432

1244

20

10

28

36

null 1244

null 4432

null null

null 124

null null

rvores N-rias
Veremos cdigo para:
Inicializao
Insero
Exibio
Busca

8
15
20

10

23
28

2
36

rvores N-rias
Antes de mais nada, vamos definir as estruturas
necessrias...
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
typedef int TIPOCHAVE;

typedef struct no {
TIPOCHAVE chave;
/*Aqui vo outros dados*/
struct no *primFilho;
struct no *proxIrmao;
} NO;
typedef NO* PONT;

rvores N-rias Inicializao


Para inicializar, temos que primeiro criar um n na
memria
PONT criaNovoNo(TIPOCHAVE ch){
PONT novo =
(PONT)malloc(sizeof(NO));
novo->primFilho = NULL;
novo->proxIrmao = NULL;
novo->chave = ch;
return(novo);
}

PONT inicializa(TIPOCHAVE ch) {


return(criaNovoNo(ch));
}
...
int main() {
PONT r = inicializa(8);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
if (!p) pai->primFilho = filho;
else {
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
if (!p) pai->primFilho = filho;
Verificamos se o pai
else {
existe
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
if (!p) pai->primFilho = filho;
Criamos o n para o
else {
filho
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
Verificamos o
if (!p) pai->primFilho = filho;
else {
primognito desse pai
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
Se no houver
if (!p) pai->primFilho = filho;
primognito, o novo
else {
while (p->proxIrmao)
n o primeiro filho
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
if (!p) pai->primFilho = filho;
Do contrrio, vamos
else {
ao ltimo filho
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Insero


bool insere(PONT raiz, TIPOCHAVE novaChave, TIPOCHAVE chavePai){
PONT pai = buscaChave(chavePai,raiz);
if (!pai) return(false);
PONT filho = criaNovoNo(novaChave);
PONT p = pai->primFilho;
Colocamos o novo n
if (!p) pai->primFilho = filho;
else {
como caula
while (p->proxIrmao)
p = p->proxIrmao;
p->proxIrmao = filho;
}
return(true);
}

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

8
15
20
Sada:

10

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

8
15
20
Sada:

10

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

8
15
20
Sada:

10

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

8
15
20

10

Sada: 8(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15
20

10

Sada: 8(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15
20

10

Sada: 8(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15
20

10

Sada: 8(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15
20

10

Sada: 8(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15
20

10

Sada: 8(15(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

Sada: 8(15(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

Sada: 8(15(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

Sada: 8(15(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

Sada: 8(15(

23
28

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

23
28

Sada: 8(15(20(

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

p
p

20

10

23
28

Sada: 8(15(20(

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

p
p

20

10

23
28

Sada: 8(15(20(

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

p
p

20

10

23
28

Sada: 8(15(20()

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

15

20

10

23
28

Sada: 8(15(20()

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

p
p

20

15
10

23
28

Sada: 8(15(20()

2
36

rvores N-rias Exibio


void exibirArvore(PONT raiz){
if (raiz == NULL) return;
printf("%d(",raiz->chave);
PONT p = raiz->primFilho;
while (p) {
exibirArvore(p);
p = p->proxIrmao;
}
printf(")");
}

8
15
20

10

23
28

2
36

Aps o fim do algoritmo, teremos


Sada: 8(15(20()10()28())23()2(36()7()))

rvores N-rias Busca


PONT buscaChave(TIPOCHAVE ch, PONT raiz){
if (raiz == NULL) return NULL;
if (raiz->chave == ch) return raiz;
PONT p = raiz->primFilho;
while(p) {
PONT resp = buscaChave(ch, p);
if (resp) return(resp);
p = p->proxIrmao;
}
return(NULL);
}

rvores N-rias Busca


PONT buscaChave(TIPOCHAVE ch, PONT raiz){
if (raiz == NULL) return NULL;
if (raiz->chave == ch) return raiz;
PONT p = raiz->primFilho;
while(p) {
Efetuamos
PONT resp = buscaChave(ch, p);
raiz
if (resp) return(resp);
p = p->proxIrmao;
}
return(NULL);
}

a busca na

rvores N-rias Busca


PONT buscaChave(TIPOCHAVE ch, PONT raiz){
if (raiz == NULL) return NULL;
if (raiz->chave == ch) return raiz;
PONT p = raiz->primFilho;
while(p) {
Se no encontrarmos,
PONT resp = buscaChave(ch, p);
olhamos os filhos
if (resp) return(resp);
p = p->proxIrmao;
}
return(NULL);
}

rvores N-rias Busca


PONT buscaChave(TIPOCHAVE ch, PONT raiz){
if (raiz == NULL) return NULL;
if (raiz->chave == ch) return raiz;
E, para cada filho,
PONT p = raiz->primFilho;
while(p) {
buscamos na
PONT resp = buscaChave(ch, p);
subrvore de que ele
if (resp) return(resp);
p = p->proxIrmao;
raiz
}
return(NULL);
}

rvores N-rias Busca


PONT buscaChave(TIPOCHAVE ch, PONT raiz){
if (raiz == NULL) return NULL;
if (raiz->chave == ch) return raiz;
Se no encontrarmos
PONT p = raiz->primFilho;
while(p) {
no pai e nem nos
PONT resp = buscaChave(ch, p);
descendentes, no
if (resp) return(resp);
p = p->proxIrmao;
est l
}
return(NULL);
}

rvores N-rias
E a excluso?

rvores N-rias
E a excluso? A excluso vai depender muito do
contexto em que ela ser usada

rvores N-rias
E a excluso? A excluso vai depender muito do
contexto em que ela ser usada
Pode at nem ser necessria

rvores N-rias
E a excluso? A excluso vai depender muito do
contexto em que ela ser usada
Pode at nem ser necessria
Em especial, temos que decidir o que fazer com os ns
filhos do n excludo

rvores N-rias
E a excluso? A excluso vai depender muito do
contexto em que ela ser usada
Pode at nem ser necessria
Em especial, temos que decidir o que fazer com os ns
filhos do n excludo
Sero adotados por algum? Ou morrem junto?

rvores N-rias
E a excluso? A excluso vai depender muito do
contexto em que ela ser usada
Pode at nem ser necessria
Em especial, temos que decidir o que fazer com os ns
filhos do n excludo
Sero adotados por algum? Ou morrem junto?
uma deciso de projeto... exerccio para voc

AULA 19
ESTRUTURA DE DADOS
rvores N-rias
Norton T. Roman & Luciano A. Digiampietri

Você também pode gostar