Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria...

83
Ciência da Computação Ciência da Computação Estrutura de Dados I Estrutura de Dados I Professores: Professores: Artur Henrique Kronbauer Artur Henrique Kronbauer José Maria David José Maria David Maria Luiza Braga Maria Luiza Braga 1

Transcript of Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria...

Page 1: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

Ciência da ComputaçãoCiência da Computação

Estrutura de Dados IEstrutura de Dados I

Professores:Professores:

Artur Henrique KronbauerArtur Henrique Kronbauer

José Maria DavidJosé Maria David

Maria Luiza BragaMaria Luiza Braga

1

Page 2: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

2

PonteirosPonteiros

• Definição– Variáveis que contém um endereço de memória. Se

uma variável contém o endereço de outra, então a primeira (o ponteiro) aponta para a segunda.

– “X” o “ponteiro”, aponta para o “inteiro” A.

– Possibilitam manipular endereços de memória e informações contidas nesses endereços.

A B X Nome das Variáveis

Informação de Memória

1022 1038 1042 1061 1084 1092 Endereços de Memória

8 10225

Page 3: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

3

PonteirosPonteiros

• Operadores

– & - (E comercial) - fornece o endereço de determinada variável. Atribui o endereço de uma variável para um ponteiro.

Obs: Não confundir com o operador lógico de operações de baixo nível, de mesmo símbolo.

– * - (Asterisco) – permite acessar o conteúdo de uma variável, cujo endereço é o valor do ponteiro. Devolve o valor endereçado pelo ponteiro.

Obs: Não confundir com o operador aritmético de multiplicação de mesmo símbolo.

Page 4: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

4

PonteirosPonteiros

• Exemplo 1: Utilização dos operadores & e *.

#include <stdio.h>;void main(){ int destino, origem;

int *m; origem = 10; m = &origem; destino = *m; printf(“Valor da variavel destino:

%i”,destino);}

Declaração de um ponteiro.

m obtém o endereço de memória da variável origem.

destino recebe a informação contida no endereço apontado por m.

destino origem m Nome das Variáveis

Informação de Memória

1038 1061 1092 Endereços de Memória

10 10 1061

Page 5: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

5

PonteirosPonteiros

• Exemplo 2: Atribuição de ponteiros

#include <stdio.h>;void main(){ float destino, origem;

float *end1, *end2; origem = 5.5;

end1 = &origem; end2 = end1; destino = *end2; printf(“O resultado é : %f”,destino);

}

Declaração dos ponteiros.

end1 recebe o endereço de memória da variável origem.

end2 recebe a posição de memória da variável origem que está guardada em end1.

destino recebe a informação contida no endereço apontada por end2.

destino origem end1 end2 Nome das Variáveis

Informação de Memória

1022 1038 1084 1092 Endereços de Memória

5.5 1038 10385.5

Page 6: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

6

Ponteiros e as Funções malloc e freePonteiros e as Funções malloc e free• malloc(): Essa função atribui a um ponteiro uma

determinada região de memória de acordo com o tipo do ponteiro.– malloc() está definido na biblioteca stdlib.h do C

• Veja o código a seguir:

int *p, *q; int x; p = (int *) malloc (sizeof (int)); *p = 3; q = p;(a) printf ("%d %d \n", *p, *q); x = 7; *q = x;(b) printf ("%d %d \n", *p, *q);(c) p = (int *) malloc (sizeof (int));(d) *p = 5;

printf ("%d %d \n", *p, *q);

(a) p

q

(b) P x

q

x

(c) p q

x

(d) p q

3

7 7

7 7

5 77

Page 7: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

7

Ponteiros e as Funções malloc e freePonteiros e as Funções malloc e free

• Free: Essa função libera para o sistema operacional uma determinada região de memória alocada por um ponteiro.

• Veja o Código a seguir:

int *p, *q; int x; p = (int *) malloc (sizeof (int)); *p = 5; q = (int *) malloc (sizeof (int));(a) *q = 8;(b) free(p);(c) p = q; q = (int *) malloc (sizeof (int));(d) *q = 6;

printf ("%d %d \n", *p, *q);

(a) p q

(b) p q

(c) p

q

(d) p q

5

8

8

8

6

8

Page 8: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

8

Vetores – Estruturas EstáticasVetores – Estruturas Estáticas

• Definição– São tipos de dados compostos ou estruturados.

– É um conjunto finito e ordenado de dados.

– São chamados de estruturas estáticas porque não podem mudar de tamanho durante a execução do programa, ou seja, preservam o tamanho definido pelo programador no momento do desenvolvimento do software.

– São formados por índices e informações.• Índices: Definem as posições de armazenamento

da estrutura• Informações: São os dados armazenados e

identificados pelos índices. 1 4 14 6 21 18 10 25 7 5

0 1 2 3 4 5 6 7 8 9 índices

informação

Page 9: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

9

Vetores – Estruturas EstáticasVetores – Estruturas Estáticas

• Exemplo de manipulação de vetores

#include <stdio.h>#include <stdlib.h>#define MAX 4

int insere_elemento(int [], int);int remove_elemento(int[], int);

void main(){ int vetorA[MAX], numero, espaco=0, i; for (i=0; i < MAX; vetorA[i++]=0); do

espaco=insere_elemento(vetorA, random(100)); while (espaco == 0); do

espaco=remove_elemento(vetorA, random(100)); while (espaco == 0);}

Inclusão das bibliotecas

Declaração de uma constante

Definição dos protótipos, ou seja, especificação das funções do programa

Inicialização do vetor

Declaração das variáveis

Page 10: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

10

Vetores – Estruturas EstáticasVetores – Estruturas Estáticas

int insere_elemento(int vetor[MAX], int elemento){ int i=0; while (vetor[i] != 0 && i < MAX) i++; if (i >= MAX) return(1); // indica que não existe mais espaço else vetor[i]=elemento; return(0); // inserção bem sucedida}

int remove_elemento(int vetor[MAX], int elemento){ int i=0; while (vetor[i] != elemento && i < MAX) i++; if (i >= MAX) return(1); // indica elemento não encontrado vetor[i]=0; return(0); // remoção bem sucedida}

Parâmetros recebidos

Inserção do novo elemento

Tipo de retorno da função

Page 11: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

11

Vetores – Estruturas EstáticasVetores – Estruturas Estáticas

• Operações com strings de caracteres

• Exemplo1: Tamanho de uma String

– Em C – Em peseudocódigo

int tamanho(char string[]) inteiro tamanho(caracter string[])

{ int i=0; início

while (string[i] != ‘\0’) enquanto (string[i] <> ‘\0’)

i++; i=i+1;

return i; fim-enquanto;} retorna i;

fim;

• Exemplo2: Concatenação de Stringsvoid concatena(char s1[], char s2[]){ for (int i=0; s1[i]!= ‘\0’;i++); for (int j=0; s2[j]!= ‘\0’;s1[i++]=s2[j++]); s1[i++]=‘\0’ printf("A palavra concatenada é %s",s1);}

Page 12: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

12

Ponteiros e VetoresPonteiros e Vetores• Definição

– Na verdade o nome de um vetor é um ponteiro. Portanto, podemos trabalhar com vetores de duas formas abaixo.

void main ()

{ float vet[50];

int i;

for (i=0;i<50;i++)

vet[i]=0.0;

}

– No 1o. código, cada vez que se faz vet[i] o programa tem que calcular o deslocamento para dar ao ponteiro. Ou seja, o programa tem que calcular 50 deslocamentos. No segundo o único cálculo que deve ser feito é o de um incremento de ponteiro, que é muito mais rápido que calcular 50 deslocamentos completos.

void main (){ float vet[50]; float *p; int i; p=vet; for (i=0;i<50;i++) { *p=0.0; p++; }}

Page 13: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

13

Ponteiros e VetoresPonteiros e Vetores

• Manipulação de vetores através de ponteiros– Como podemos indexar o nome de um vetor e o nome de

um vetor é um ponteiro constante, então podemos também indexar um ponteiro qualquer.

void main()

{ int vet [10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int *p;

p=vet;

printf ("O terceiro elemento do vetor é: %d",p[2]);

printf ("O quinto elemento do vetor é: %d",*(p+4));

printf ("O sétimo elemento do vetor é: %d",vet[7]);

}

– Podemos ver que p[2] equivale a *(p+2) que equivale a

vet[2].

Mostra 3

Mostra 5

Mostra 8

Page 14: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

14

Estruturas – tipos definidos pelos usuáriosEstruturas – tipos definidos pelos usuários• Definição

– Uma estrutura agrupa várias variáveis numa só. Funciona como uma ficha pessoal que tenha nome, telefone e endereço. A ficha seria uma estrutura. A estrutura, então, serve para agrupar um conjunto de dados não similares, formando um novo tipo de dados.

• Declaração • Exemplostruct nome_do_tipo_da_estrutura { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; } variáveis_estrutura;

– No exemplo foram declaradas duas variáveis, clientenovo e clienteant que são do tipo da estrutura, isto é, possuem os campos num_conta, tipo_conta, nome e saldo.

struct conta

{ int num_conta;

char tipo_conta;

char nome[80];

float saldo;

};

struct conta clientenovo,

clienteant;

Page 15: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

15

Estruturas – Tipos definidos pelos usuáriosEstruturas – Tipos definidos pelos usuários• Uma estrutura pode conter outra estrutura.

struct data struct conta { int mes; { int num_conta;

int dia; char tipo_conta; int ano; char nome[80];}; float saldo; struct data ultpag;

}

• Inicializando estruturas– struct conta cliente = {12345, 'R', "Joao", 586.30, 5, 24, 30};

• Processando uma estrutura– Acessando num_conta: cliente.num_conta

– Acessando o 3a caracter do vetor nome: cliente.nome[2]

• O uso do operador ponto pode ser estendido a vetores– struct conta cliente[100];

– número da conta do 14o cliente: cliente[13].num_conta

– mês do último pagamento do 14o cliente: cliente[13].ultpag.mes

Page 16: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

16

Estruturas e PonteirosEstruturas e Ponteiros• Os ponteiros para uma estrutura funcionam como os

ponteiros para qualquer outro tipo de dados. struct data { int mes;

int dia; int ano;} nascimento, *ptr;

• Possibilidades de definição dos ponteiros. – A primeira é apontá-lo para uma variável struct já

existente, da seguinte maneira: struct data nascimento;

struct data *ptr; ptr = &nascimento;

– A segunda é alocando memória usando malloc(): struct data *ptr = (struct data *) malloc (sizeof (struct

data)); ptr->dia=15;

ptr -> mes equivale anascimento.mes

Ponteiros usam o operador ->

sizeof é o operador que retorna o tamanho de uma variável ou tipo.

Page 17: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

17

Estruturas auto-referenciaisEstruturas auto-referenciais• Estruturas auto-referenciais são estruturas que possuem

um ponteiro como campo do tipo da própria estrutura.

• Definição • Exemplo struct tag

{ membro 1;membro 2;

...struct tag *nome;

};

• Exemplo da aplicabilidade. – Listas Encadeadas

struct lista_elem{ char item[40]; struct lista_elem *prox;}

Cabeça da Lista

Ponteiro parao primeiro nodo

DadosPróximo

DadosPróximo

DadosPróximo

DadosPróximo null

nodo nodonodonodo

Page 18: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

18

UniõesUniões• Definição

– Uma declaração union determina uma única localização de memória onde podem estar armazenadas várias variáveis diferentes. A declaração de uma união é semelhante à declaração de uma estrutura:

union angulo { float graus; float radianos; };

– No exemplo temos duas variáveis (graus e radianos) que, apesar de terem nomes diferentes, ocupam o mesmo local da memória. Isto quer dizer que só gastamos o espaço equivalente a um único float.

– Uniões podem ser criadas também com variáveis de diferentes tipos. Neste caso, a memória alocada corresponde ao tamanho da maior variável no union.

Page 19: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

19

UniõesUniões• Exemplo

#include <stdio.h> union angulo { int graus; float radianos; }; void main() { union angulo ang; char op; printf("\nNumeros em graus ou radianos? (G/R):"); scanf("%c",&op); if (op == ‘G’) { ang.graus = 180; printf("\nAngulo: %d\n",ang.graus); } else if (op == ‘R’) { ang.radianos = 3.1415; printf("\nAngulo: %f\n",ang.radianos); } else printf("\nEntrada invalida!!\n"); }

Page 20: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

20

Lista EncadeadaLista Encadeada em Estrutura Estáticaem Estrutura Estática

• Definição– Como uma lista é apenas um conjunto de nós, um vetor de

nós é uma das formas de representa-lá. Entretanto, os nós não podem ser ordenados pelos índices do vetor; cada um deve conter em si mesmo um ponteiro para o seu sucessor.

– A forma mais coerente de representar a estrutura é ter uma lista de endereços e uma lista de dados no mesmo vetor. Ambas as listas são acessadas através de variáveis inteiras indicando o início e o final de cada lista. No final de cada lista o campo próximo é igualado a –1.

• Representação Estrutural

9 8 7 25 5 45 16 2 18 21

0 1 2 3 4 5 6 7 8 9 índices

informação

-1 9 8 -1 7 6 4 5 3 1 próximo

Inicio da lista de dados

Inicio da lista de endereços

Final da lista de endereços

Final da lista de dados

Page 21: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

21

Lista Encadeada em Estrutura EstáticaLista Encadeada em Estrutura Estática#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <string.h>

void inicializa_enderecos(void);int obtem_endereco(void);void incluir(int, int);void excluir(int);void devolve_endereco(int);void mostra_dados(void);

const espaco=10;

struct nodo{ int info; int prox;} typedef T_nodo;

T_nodo vet[10];int inicio_led=-1;int inicio_dados=-1;int fim_dados=-1;

void main(){ char op[1]; int informacao,endereco; inicializa_enderecos(); do { printf("(I)ncluir (E)xcluir (F)inalizar :\n"); gets(op); if (strcmp(op,"i")==0 || strcmp(op,"e")==0) { printf("Entre com o numero : "); scanf("%d",&informacao); if (strcmp(op,"i")==0) { endereco=obtem_endereco();

if (endereco != -1) incluir(endereco,informacao);

} else if (strcmp(op,"e")==0) { excluir(informacao); } mostra_dados(); } } while (strcmp(op,"f")!=0);}

Page 22: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

22

Lista Encadeada em Estrutura EstáticaLista Encadeada em Estrutura Estáticavoid inicializa_enderecos(){ int i; for (i=0; i < espaco; i++) vet[i].prox=i+1; vet[espaco-1].prox=-1; inicio_led=0; }

int obtem_endereco(){ int end; end=inicio_led; if (inicio_led == -1) { gotoxy(20,23); printf("Estouro de capacidade"); return -1; } else { inicio_led=vet[inicio_led].prox; return end; }}

void incluir(int end, int n){ if (inicio_dados == -1) inicio_dados=end; else vet[fim_dados].prox=end; fim_dados=end; vet[end].prox=-1; vet[end].info=n;}

void devolve_endereco(int end){ vet[end].prox=inicio_led; inicio_led=end; }

Page 23: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

23

Lista Encadeada em Estrutura EstáticaLista Encadeada em Estrutura Estáticavoid excluir(int n){ int atual=inicio_dados; int ant=inicio_dados; while ((vet[atual].info != n) && (vet[atual].prox != -1)) { ant=atual; atual=vet[atual].prox; } if (vet[atual].info != n) printf("Elemento Não Encontrado"); else { if (atual == inicio_dados) { inicio_dados=vet[atual].prox;

if (atual == fim_dados) fim_dados=-1;

} else if (atual == fim_dados) { fim_dados=ant;

vet[ant].prox=-1; } else vet[ant].prox=vet[atual].prox; devolve_endereco(atual); }}

Remoção no meio

Remoção no início

Remoção no final

percorre a lista de dados até achar o elemento procurado ou final da lista

Page 24: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

24

Lista Encadeada em Estrutura EstáticaLista Encadeada em Estrutura Estática

Percorre a lista de endereços

void mostra_dados(){ int atual=inicio_led; printf("Lista de Endereços"); while (atual != -1) { printf("%d \n",vet[atual].prox); atual=vet[atual].prox; } atual=inicio_dados; printf(“\nLista de Dados"); while (atual != -1) { printf("%d %d \n",vet[atual].info); atual=vet[atual].prox; }}

Percorre a lista de dados

• Desafio

Reescreva o programa anterior para trabalhar com 3 listas no mesmo vetor.

Page 25: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

25

Lista Simplesmente EncadeadaLista Simplesmente Encadeada em Estrutura em Estrutura DinâmicaDinâmica• Definição

– É uma seqüência de estruturas (elementos) interligados, com a capacidade de inserção e remoção em qualquer posição da lista.

– A cabeça da lista (nó descritor) contém um ponteiro para o primeiro elemento da lista (nodo), que armazena um conjunto de dados e um ponteiro para o nodo seguinte. Esse nodo, da mesma forma, armazena um item de dados e um ponteiro para o nodo seguinte, e assim por diante. O último nodo possui um ponteiro NULL para indicar o final da lista.

• Critério– O critério utilizado em listas determina que as inserções e

remoções podem ser realizadas em qualquer posição da lista. Por conveniência utilizaremos a inserção por ordem de chave (informação única que distingue um elemento de outro).

Page 26: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

26

Lista Simplesmente Encadeada em Estrutura Lista Simplesmente Encadeada em Estrutura DinâmicaDinâmica

/* include das bibliotecas do C */#include <string.h>#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <alloc.h>#include <process.h>

/* definição da estrutura */typedef struct nodo { int chave;

char pessoa[30];struct nodo *prox;

} T_lista;

struct nodo *inicio=NULL;

/* inclusão de protótipos */

T_lista *obtem_endereco(void);void insere_elemento(char [4], char [30]);void retira_elemento(char [4]);T_lista *consulta_elemento(char[4]); void mostra_dados(void);

Page 27: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

27

Lista Simplesmente Encadeada em Estrutura Lista Simplesmente Encadeada em Estrutura DinâmicaDinâmicavoid main()

{ int i; char codigo[4],nome[30], opcao[1]; clrscr(); do { printf("(I)ncluir (E)xcluir (C)consultar (F)inalizar : ");

gets(opcao);printf("Entre com o código da pessoa : ");if (strcmp(opcao,"E") == 0 || strcmp(opcao,"e") == 0){ gets(codigo); retira_elemento(codigo);}else if (strcmp(opcao,"I") == 0 || strcmp(opcao,"i") == 0){ gets(codigo);

printf("Entre com o nome da pessoa.. : "); gets(nome); insere_elemento(codigo,nome);

} else if (strcmp(opcao,"C") == 0 || strcmp(opcao,"c") == 0) // consulta_elemento(codigo); // mostra_dados(); } while (strcmp(opcao,"F") != 0 && strcmp(opcao,"f") != 0); clrscr();}

Desenvolva essas funções

Page 28: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

28

Lista Simplesmente Encadeada em Estrutura Lista Simplesmente Encadeada em Estrutura DinâmicaDinâmica

/* função de alocação de uma nova estrutura do tipo celula na memória e obtenção de seu endereço */

T_lista *obtem_endereco(){ T_lista *novo; novo=(T_lista *) malloc(sizeof(struct nodo)); if (novo == NULL) { gotoxy(25,22); printf("Memória insuficiente para alocar estrutura"); exit(1); } return(novo);}

Page 29: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

29

Lista Simplesmente Encadeada em Estrutura Lista Simplesmente Encadeada em Estrutura DinâmicaDinâmica

/* função que coloca o elemento dentro da lista em ordem crescente de acordo com o código = chave */

void insere_elemento(char codigo[4], char nome[30]){ T_lista *novo, *aux, *ant; novo=obtem_endereco(); aux=inicio; if ((aux == NULL) || (aux->chave > atoi(codigo))) { inicio = novo; novo->prox=aux; } else { while ((aux->chave <= atoi(codigo)) && (aux != NULL)) { ant=aux; aux=aux->prox; } novo->prox=ant->prox; ant->prox=novo; } novo->chave=atoi(codigo); strcpy(novo->pessoa,nome); }

Inserção no começo

Inserção no meio ou final da lista

Page 30: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

30

Lista Simplesmente Encadeada em Estrutura Lista Simplesmente Encadeada em Estrutura DinâmicaDinâmicavoid retira_elemento(char codigo[4])

{ T_lista *ret, *aux; if (inicio == NULL) { printf("Lista Vazia"); return; } ret=inicio; aux=inicio; if (ret->chave == atoi(codigo)) inicio = ret->prox; else { while ((ret->chave != atoi(codigo)) && (ret != NULL)) { aux=ret; ret=ret->prox; } if (ret == NULL) { printf("Elemento Inexistente");

return; } else aux->prox=ret->prox; } free(ret); }

Testa se a lista está vazia

Retira do início da lista

Retira no meio ou final da lista

Testa se a chave pesquisada não existe

Indexa os nodos

Libera da memória

Page 31: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

31

Lista Duplamente EncadeadaLista Duplamente Encadeada• Definição

– Em algumas aplicações que utilizam listas encadeadas pode ser de extrema necessidade percorre-lá da esquerda para a direita, bem como da direita para a esquerda. Este tipo de estrutura é chamada de Lista Duplamente Encadeada.

– A cabeça da lista contém dois ponteiros, um para o primeiro elemento da lista e outro para o último elemento da lista. Os nodos devem ter dois ponteiros, um para o próximo nodo e um para o nodo anterior.

• Representação EstruturalCabeça de Lista

Ponteiro parao primeiro nodoPonteiro para oúltimo nodo

nullDadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

null

Page 32: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

32

Lista Duplamente Encadeada em Estrutura Lista Duplamente Encadeada em Estrutura DinâmicaDinâmica#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <alloc.h>

#include <process.h>

typedef struct nodo

{ int chave;

char pessoa[30];

struct nodo *prox;

struct nodo *ant;

} T_lista;

typedef struct cab_lista

{ struct nodo *inicio;

struct nodo *fim;

} T_cabeca;

T_cabeca cabeca;

// protótipos do programa

void ini_cabeca();

T_lista *obtem_endereco();

void insere_elemento(char [4], char [30]);

void retira_elemento(char [4]);

T_lista *consulta_elemento(char[4]);

void mostra_dados();

Observação: As rotinas de consultar e mostrar dados devem ser desenvolvidas pelos alunos como exercício.

Page 33: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

33

Lista Duplamente Encadeada em Estrutura Lista Duplamente Encadeada em Estrutura DinâmicaDinâmicavoid ini_cabeca()

{ cabeca.inicio=NULL;

cabeca.fim=NULL;

}

T_lista *obtem_endereco()

{ T_lista *novo;

novo=(T_lista *) malloc(sizeof(struct nodo));

if (novo == NULL)

{ printf("Memória insuficiente para alocar estrutura");

exit(1);

}

return(novo);

}

Page 34: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

34

Lista Duplamente Encadeada em Estrutura Lista Duplamente Encadeada em Estrutura DinâmicaDinâmicavoid insere_elemento(char codigo[4], char nome[30])

{ T_lista *novo, *aux, *esquerda;

novo=obtem_endereco();

aux=cabeca.inicio;

esquerda=cabeca.inicio;

if ((aux == NULL) || (aux->chave > atoi(codigo)))

{ cabeca.inicio = novo;

novo->prox=aux;

novo->ant=NULL;

if (novo->prox == NULL)

cabeca.fim = novo;

else

aux->ant = novo;

}

else

{ while ((aux->chave <= atoi(codigo)) && (aux->prox != NULL))

{ esquerda=aux;

aux=aux->prox;

}

Page 35: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

35

Lista Duplamente Encadeada em Estrutura Lista Duplamente Encadeada em Estrutura DinâmicaDinâmica

if ((aux->prox == NULL) && (aux->chave <= atoi(codigo)))

{ cabeca.fim = novo;

novo->prox = NULL;

novo->ant = aux;

aux->prox = novo;

}

else

{ novo->prox=aux;

novo->ant=esquerda;

aux->ant=novo;

esquerda->prox=novo;

}

}

novo->chave=atoi(codigo);

strcpy(novo->pessoa,nome);

}

Page 36: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

36

Lista Duplamente Encadeada em Estrutura Lista Duplamente Encadeada em Estrutura DinâmicaDinâmicavoid retira_elemento(char codigo[4])

{ T_lista *ret, *direita, *esquerda;

if (cabeca.inicio == NULL)

{ printf("Lista Vazia");

return;

}

ret=cabeca.inicio;

if (ret->chave == atoi(codigo))

{ cabeca.inicio=ret->prox;

direita=ret->prox;

direita->ant=NULL;

}

else

{ while ((ret->chave != atoi(codigo)) && (ret != NULL))

{ esquerda=ret;

ret=ret->prox;

}

if (ret == NULL)

{ printf("Elemento Inexistente");

return; }

else

{ esquerda->prox=ret->prox;

direita=ret->prox;

direita->ant=esquerda;

if (ret == cabeca.fim)

cabeca.fim=esquerda;

}

}

free(ret);

}

Page 37: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

37

Listas CircularesListas Circulares• Definição

– Em algumas aplicações que utilizam listas encadeadas pode ser de extrema necessidade que o último nodo aponte para o primeiro. Este tipo de estrutura é chamada de Lista Circular.

• Representação Estrutural da lista Circular

• Representação Estrutural da lista Circular Duplamente Encadeada

Cabeça da Lista

Ponteiro parao primeiro nodo

DadosPróximo

DadosPróximo

DadosPróximo

DadosPróximo

nodo nodonodonodo

Cabeça de Lista

Ponteiro parao primeiro nodoPonteiro para oúltimo nodo

DadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

DadosPróximoAnterior

nodo

Page 38: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

38

Filas e PilhasFilas e Pilhas• Definição

– Para determinadas aplicações é imposto um critério que restringe a inserção/retirada dos elementos que compõem um conjunto de dados.

• Critério de Pilha

• Critério de Fila

UEPSUEPS:: dentre os elementos que ainda permanecemdentre os elementos que ainda permanecemno conjunto, ono conjunto, o primeiro elemento a serprimeiro elemento a serretirado é o retirado é o últimoúltimo que tiver sido inserido. que tiver sido inserido.

PEPSPEPS:: dentre os elementos que ainda permanecemdentre os elementos que ainda permanecemno conjunto, ono conjunto, o primeiro elemento a serprimeiro elemento a ser

rretirado é o etirado é o primeiroprimeiro que tiver sido inserido. que tiver sido inserido.

Page 39: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

39

FilaFila

• PEPS (O Primeiro a Entrar é o Primeiro a Sair)

A B C

B C

B C D E

(a)

(b)

(c)

Início Final

Início

Início

Final

Final

insere (A)insere (B)insere (C)

remove(ponteiro)

insere (D)insere (E)

Page 40: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

40

Fila em Estrutura EstáticaFila em Estrutura Estática#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#define MAX 10

typedef struct fila

{ int elemento[MAX];

int inicio;

int fim;

int tam;

} T_fila;

T_fila *inicializaFila();

void insere_fila(int, T_fila *);

int retira_fila(T_fila *);

void mostra_dados();

void main()

{ char opcao[1],valor[4];

T_fila *pfila;

pfila=inicializaFila();

do

{ printf("(I)ncluir (E)xcluir (F)inalizar : ");

gets(opcao);

if (strcmp(opcao,"E") == 0 )

itoa(retira_fila(pfila),valor,10);

else if (strcmp(opcao,"I") == 0 )

{ printf("Entre com o nº a incluir : ");

gets(valor);

insere_fila(atoi(valor),pfila);

}

// mostra_dados();

} while (strcmp(opcao,"F") != 0);

}

Exercício p/ os alunos

Page 41: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

41

Fila em Estrutura EstáticaFila em Estrutura Estática

T_fila *inicializaFila()

{ T_fila *nova_fila;

nova_fila=(T_fila *) malloc(sizeof(struct fila));

if (nova_fila == NULL)

{ printf("Não existe memória para criar a estrutura");

exit(1);

}

nova_fila->inicio=0;

nova_fila->fim=-1;

nova_fila->tam=0;

return(nova_fila);

}

void insere_fila(int valor, T_fila *pfila)

{ if (pfila->tam == MAX)

{ printf("Fila Cheia");

return;

}

pfila->fim = (pfila->fim + 1) % MAX;

pfila->elemento[pfila->fim] = valor;

pfila->tam++;

}

int retira_fila(T_fila *pfila)

{ int valor;

if (pfila->tam == 0)

{ printf("Lista Vazia");

return(-1);

}

valor = pfila->elemento[pfila->inicio];

pfila->inicio=(pfila->inicio+1) % MAX;

pfila->tam--;

return(valor);

}

Page 42: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

42

Fila em Estrutura DinâmicaFila em Estrutura Dinâmica#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

typedef struct nodo

{ int chave;

char pessoa[30];

struct nodo *prox;

} T_fila;

typedef struct cab_lista

{ struct nodo *inicio;

struct nodo *fim;

} T_cabeca;

T_cabeca cabeca;

void ini_cabeca(void);

T_fila *obtem_endereco(void);

void insere(char [4], char [30]);

void retira(void);

void mostra_dados(void);

Exercício p/ os alunos

void main(){ int i; char codigo[4],nome[30], opcao[1]; ini_cabeca(); do

{ printf("(I)ncluir (E)xcluir (F)inalizar : ");

gets(opcao);

if (strcmp(opcao,"E") == 0)

{ retira();

mostra_dados();

}

else if (strcmp(opcao,"I") == 0)

{ printf("Entre com o código da pessoa : ");

gets(codigo);

printf("Entre com o nome da pessoa.. : ");

gets(nome);

insere(codigo,nome);

mostra_dados();

}

} while (strcmp(opcao,"F") != 0);

}

Page 43: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

43

Fila em Estrutura DinâmicaFila em Estrutura Dinâmicavoid ini_cabeca()

{ cabeca.inicio=NULL;

cabeca.fim=NULL;

}

T_fila *obtem_endereco()

{ T_fila *novo;

novo=(T_fila *) malloc(sizeof(struct nodo));

if (novo == NULL)

{ printf("Memória insuficiente para alocar estrutura");

exit(1);

}

return(novo);

}

Page 44: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

44

Fila em Estrutura DinâmicaFila em Estrutura Dinâmica

void insere(char codigo[4], char nome[30])

{ T_fila *novo;

novo=obtem_endereco();

if (cabeca.inicio == NULL)

{ cabeca.inicio = novo;

cabeca.fim=novo;

}

else

{ cabeca.fim->prox=novo;

cabeca.fim=novo;

}

novo->prox=NULL;

novo->chave=atoi(codigo);

strcpy(novo->pessoa,nome);

}

void retira()

{ T_fila *ret;

if (cabeca.inicio == NULL)

{ printf("Fila Vazia");

return;

}

else

{ ret=cabeca.inicio;

cabeca.inicio=ret->prox;

free(ret);

if (cabeca.inicio==NULL)

cabeca.fim=NULL;

}

}

Page 45: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

45

PilhaPilha

• UEPS (O Último a Entrar é o Primeiro a Sair)

A B C

A B

A B D E

(a)

(b)

(c)

Início Final

Início

Início

Final

Final

insere (A)insere (B)insere (C)

remove(ponteiro)

insere (D)insere (E)

Page 46: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

46

PilhaPilha em Estrutura Estáticaem Estrutura Estática#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#define MAXPILHA 10

typedef struct pilha

{ int valor[MAXPILHA];

int topo;

} T_pilha;

T_pilha *inicializaPilha();

void empilha(int, T_pilha *);

int desempilha(T_pilha *);

void mostra_dados();

void main()

{ char opcao[1],valor[4];

T_pilha *ppilha;

ppilha=inicializaPilha();

do

{ printf("(I)ncluir (E)xcluir (F)inalizar : ");

gets(opcao);

if (strcmp(opcao,"E") == 0)

itoa(desempilha(ppilha),valor,10);

else if (strcmp(opcao,"I") == 0)

{ printf("Entre com o n§ a incluir : ");

gets(valor);

empilha(atoi(valor),ppilha);

}

// mostra_dados();

} while (strcmp(opcao,"F") != 0);

}

Exercício p/ os alunos

Page 47: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

47

PilhaPilha em Estrutura Estáticaem Estrutura EstáticaT_pilha *inicializaPilha()

{ T_pilha *nova_pilha;

nova_pilha=(T_pilha *) malloc(sizeof(struct pilha));

if (nova_pilha == NULL)

{ printf("Não existe memória p/ criar a estrutura");

exit(1);

}

nova_pilha->topo=0;

return(nova_pilha);

}

void empilha(int v, T_pilha *ppilha)

{ if (ppilha->topo >= MAXPILHA)

{ printf("Pilha Cheia");

return;

}

ppilha->valor[ppilha->topo] = v;

ppilha->topo++;

}

int desempilha(T_pilha *ppilha)

{ if (ppilha->topo == 0)

{ printf("Pilha Vazia");

return(-1);

}

ppilha->topo--;

return(ppilha->valor[ppilha->topo]);

}

como consultar um elemento

Page 48: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

48

PilhaPilha em Estrutura Dinâmicaem Estrutura Dinâmica#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

typedef struct elemento

{ int valor;

struct elemento *prox;

} T_elemento;

struct elemento *topo=NULL;

void empilha(int, T_elemento *);

int desempilha(T_elemento *);

// void mostra_dados(void);

void main()

{ char opcao[1],valor[4];

pcabeca=ini_cabeca();

do

{ printf("(I)ncluir (E)xcluir (F)inalizar : ");

gets(opcao);

if (strcmp(opcao,"E") == 0)

itoa(desempilha(topo),valor,10);

else if (strcmp(opcao,"I") == 0)

{ printf("Entre com o nº a incluir : ");

gets(valor);

empilha(atoi(valor),topo);

}

// mostra_dados();

} while (strcmp(opcao,"F") != 0);

}

Exercício p/ os alunos

Page 49: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

49

PilhaPilha em Estrutura Dinâmicaem Estrutura Dinâmicaint desempilha(T_elemento *ppilha)

{ int v;

if (ppilha == NULL)

{ printf("Pilha Vazia");

return(-1);

}

v = ppilha->valor;

topo=ppilha->prox;

free(ppilha);

return(v);

}

void empilha(int valor, T_elemento *ppilha)

{ T_elemento *novo;

novo=(T_elemento *) malloc(sizeof(struct elemento));

if (novo == NULL)

{ printf(" Memória insuficiente ");

exit(1);

}

novo->valor = valor;

novo->prox = ppilha;

topo = novo;

}

Page 50: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

50

RecursividadeRecursividade• Definição

– Pode ser considerada um método eficaz para resolver um problema originalmente complexo, reduzindo-o em pequenas ocorrências do problema principal. Dividie para conquistar. Resolvendo, isoladamente, cada uma das pequenas partes, podemos obter a solução do problema original como um todo.

• Características de uma função recursiva– Definição de parâmetros; – Condição de parada da recursão, para que a rotina não seja chamada

infinitamente;– Chamada da função dentro dela própria;

• Rotinas recursivas e pilhas– O controle de chamadas e de retorno de rotinas é efetuado por uma pilha

(criada e mantida dinamicamente pelo sistema). Quando uma rotina é chamada, empilha-se o endereço da rotina e todas as variáveis locais são recriadas. Quando ocorre o retorno da rotina as variáveis locais que foram criadas deixam de existir.

• Vantagens– Facilidade na resolução de alguns tipos de problemas.

• Desvantagens– Uso demasiado dos recursos computacionais de um computador.

Page 51: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

51

RecursividadeRecursividade

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

int busca_linear(int, int);

int busca_binaria(int,int, int);int fat(int);

const total=10;

int vet[10];

void main()

{ int i, numero, indice;

char op;

printf("Entre com 10 números");

for (i=0; i < total; i++)

scanf("%d",&vet[i]);

printf("Entre com o numero a pesquisar e calcular o fatorial");

scanf("%d",&numero);

printf("Qual a pesquisa? (B)inaria ou (L)inear");

scanf("%c",&op);

if (op == 'l')

indice=busca_linear(numero,0);

else

indice=busca_binaria(numero,0,total);

if (indice == -1)

printf("Elemento não encontrado");

else

printf("Elemento encontrado no ¡ndice : %d",indice);

numero=fat(numero); printf("O fatorial e : %d ",numero);}

Programa que de-monstra Busca Biná-ria, Busca Linear e Cálculo do Fatorial de forma recursiva.

Page 52: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

52

RecursividadeRecursividadeint busca_linear(n,i)

{ if ((i < total) && (vet[i] != n))

{ i=busca_linear(n,i+1);

return(i);

}

else

{ if (i == total)

return(-1);

else

return(i);

}

}

int busca_binaria(n,inicio,fim)

{ int meio;

if (inicio <= fim)

{ meio = (inicio+fim)/2;

if (vet[meio] == n)

return meio;

else if (vet[meio] < n)

busca_binaria(n,meio+1,fim);

else

busca_binaria(n,inicio,meio-1);

}

else

return -1;

}

int fat(int n){ int res; if (n == 0) return 1; else { res = fat(n-1); res = res * n; return res; }}

Parâmetros

Variáveis locais

Condição de parada

Chamada da própria função

Page 53: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

53

ÁrvoresÁrvores• Definição:

– Relação de hierarquia ou de composição entre os dados (nós).– Conjunto finito T de um ou mais nós, tais que:

(a) existe um nó denominado raiz da árvore;

(b) os demais nós formam m >= 1 conjuntos disjuntos S1,...,Sm,

onde cada um desses conjuntos é uma árvore.– As árvores Si recebem a denominação de Sub-árvores.

• Terminologia:

– Cada nó da árvore é a raiz de uma Sub-árvore.– O número de Sub-árvores de um nó é o grau daquele nó.– Um nó de grau igual a zero é denominado folha ou nó terminal.– A raiz da árvore tem nível 0.– Os demais nós: nível = número de "linhas" que o liga à raiz.– Altura: nível mais alto da árvore.

Page 54: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

54

ÁrvoresÁrvores

• Representação Estrutural:

Árvore com altura igual a 3.

A

B C D

E F G H

I J K

Grau = 1; Nível = 1

Grau = 3; Nível = 2

Grau = 0; Nível = 3

Grau = 3; Nível =0 (raiz)

Grau = 0 (Folha)

Page 55: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

55

Árvores BináriasÁrvores Binárias

• Definição:– Uma árvore binária é uma estrutura de dados útil quando

precisam ser tomadas decisões bidirecionais em cada ponto de um processo.

– O Grau de cada nó é menor ou igual a 2 (Sub-árvores da esquerda e da direita).

– Se grau = 1, deve ser especificado se a sua Sub-árvore é a da esquerda ou a da direita.

– Árvore Estritamente Binária: é a árvore onde todo o nó que não é folha possuí Sub-árvores a esquerda e a direita.

– Uma árvore binária completa é uma árvore estritamente binária sendo que todas as folhas devem estar no mesmo nível.

Page 56: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

56

Árvores BináriasÁrvores Binárias

• Representação Estrutural:

• Como construir uma árvore?• Como percorrer uma árvore ? • Aplicações de árvores binárias• Exemplos:

Árvore Estritamente Binária Árvore Binária Completa

5

2 7

1 4 6 9

4

2 8

9

5

6

7A

B C

D E

F G

Page 57: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

57

Árvores Binárias - ConstruçãoÁrvores Binárias - Construção

• Definição:– “Uma árvore binária é formada por um conjunto finito de nós.

Este conjunto ou é vazio, ou consiste de um nó raiz com duas sub-árvores binárias disjuntas, denominadas sub-árvores da esquerda e da direita”.

procedimento constroi (a:arvore)

var s: pilha; dado: info; p, q: ref no;inicio

leia (dado);Se dado <> '.' entãoinicio

Aloque (a); Setinfo(a, dado); /* retorna a.informacao <- dado */ constroi (esquerda(a)); constroi (direita(a));

fimsenão p <- NULO;Fim-se

Fim.

Page 58: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

58

Árvores Binárias - ConstruçãoÁrvores Binárias - Construçãotipo no: reg ( esquerda : ref nó;

informação : info;

direita : ref nó)

tipo arvore : ref nó;

procedimento constroi (a:arvore)

var s: pilha; dado: info; p, q: ref no;

Inicio

Inicializa (s);

leia (dado);

Se dado <> '.' então

Inicio

Aloque (p);

a <- p;

Setinfo(p, dado); /* retorna p.informacao <- dado */

lado<- e; /* lado = e ou d */

Empilha (s, p);

Enqto. (pilha não vazia) faça

inicio

leia (dado);

Se (lado = e) então /* esquerda */

Se (dado <> '.‘) então

inicio

q <- p; Aloque (p);

Setesq(q,p); /* q.esquerda <- p */

Setinfo(p,dado); /* p.informacao <- dado

*/

Empilha(s, q);

fim

senão /* esquerda vazia' */ inicio Setesq (p, NULO); lado <- d; fim senão /* lado = d */

Se (dado = '.' ) então /* direita */ inicio Setdir (p, NULO); p <- topo(s); Desempilha (s); fim senão /* direita*/ inicio q <- p; Aloque (p); Setdir (q, p); Setinfo (p, dado); lado <- e; fim fim /* fim Se lado = e */

fim /* fim enqto. pilha vazia */ senão /* dado = '.' */ a <- NULO;fim

Proc Setinfo(p: ref no, dado: info)

p.informacao <- dado;

Proc Setesq(p, q: ref no)

p.esquerda <- q;

Proc Setdir(p, q: ref no)

p.direita <- q;

Page 59: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

59

Árvores Binárias - PercursoÁrvores Binárias - Percurso• A natureza recursiva de uma árvore binária:

– Existem três métodos recursivos para que possamos percorrer uma árvore passando por todos os seus elementos:

– Em Pré-ordem1º. visitamos a raiz2º. Sub-árvore esq. em pré-ordem (Centro, Esquerda, Direita)3º. Sub-árvore dir. em pré-ordem

– Em Ordem1º. Sub-árvore esq. em ordem2º. visitamos a raiz (Esquerda, Centro, Direita)3º. Sub-árvore dir. em ordem.

– Em Pós- Ordem1º. Sub-árvore esq. em pós-ordem2º. Sub-árvore dir. em pós-ordem (Esquerda, Direita, Centro)3º. Visitamos a raiz

Page 60: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

60

Árvores Binárias - PercursoÁrvores Binárias - Percurso

• Exemplos:

5

4 9

8

102

6

7

3

10

5 15

19

182

17

12

4

20

6

7

Pré-ordem: 5, 4, 2, 3, 9, 7, 6, 8, 10 Em ordem: 2, 3, 4, 5, 6, 7, 8, 9, 10 Pós-ordem: 3, 2, 4, 6, 8, 7, 10, 9, 5

Pré-ordem: 20, 10, 5, 2, 4, 6, 7, 15, 12, 18, 17, 19 Em ordem: 2, 4, 5, 6, 7, 10, 12, 15, 17, 18, 19, 20 Pós-ordem: 4, 2, 7, 6, 5, 12, 17, 19, 18, 15, 10, 20

Page 61: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

61

Árvores Binárias de PesquisaÁrvores Binárias de Pesquisa

• Regra Geral de Inserção: – Os valores menores devem ficar a esquerda da raiz e os maiores a

direita.

– Os valores repetidos não devem ser inseridos.

– As inserções sempre são feitas nas folhas, dessa forma, deve se percorrer a árvore até encontrar a folha que será o pai do novo elemento a ser inserido.

– O percurso é baseado no valor da informação que está sendo inserida. Se o novo elemento for menor que o nó comparado, deve andar para a esquerda, caso contrário deve andar para a direita.

• Exemplo • Exercício:– Crie uma árvore com os seguintes nós:

14, 15, 4, 9, 7, 18, 2, 5, 16, 4, 20, 17, 9, 5.

Page 62: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

62

Árvores Binárias de PesquisaÁrvores Binárias de Pesquisa#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

typedef struct nodo

{ int info;

struct nodo *pai;

struct nodo *f_esq;

struct nodo *f_dir;

char deletado;

} T_nodo;

T_nodo *raiz;

T_nodo *cria_nodo(int,T_nodo*);

void insere(int);

T_nodo *consulta(int);

void ordem(T_nodo *);

void pre_ordem(T_nodo *);

void pos_ordem(T_nodo *);

void retira(int);

As chamadas de pré-ordem e pós-ordem foram suprimidas por serem iguais.

void main()

{ char opcao[1]; int informacao=0;

do { printf("(I)ncluir (C)onsultar (R)emover

(O)rdem Pr(E)-Ordem Pó(s)-Ordem (F)im: ");

scanf("%s",&opcao);

if ((strcmp(opcao,"I") == 0) || (strcmp(opcao,"C")

== 0) || (strcmp(opcao,"R") == 0))

{ printf("Entre com a informação : ");

scanf("%i",&informacao);

}

if (strcmp(opcao,"I") == 0)

insere(informacao);

else if (strcmp(opcao,"C") == 0)

consulta(informacao);

else if (strcmp(opcao,"O") == 0)

ordem(raiz);

else if (strcmp(opcao,"R") == 0)

retira(informacao);

} while (strcmp(opcao,"F") != 0)

}

Page 63: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

63

Árvores Binárias de PesquisaÁrvores Binárias de PesquisaT_nodo *cria_nodo(int n, T_nodo *p)

{ T_nodo *novo;

novo=(T_nodo *) malloc(sizeof(struct nodo));

if (novo == NULL)

printf("Memória insuficiente");

novo->info=n;

novo->pai=p;

novo->f_esq=NULL;

novo->f_dir=NULL;

novo->deletado='f';

return(novo);

}

void insere(int n)

{ T_nodo *p, *aux;

if (raiz == NULL)

raiz = cria_nodo(n,NULL);

else

{ p=raiz;

aux=raiz;

while (n != p->info && aux != NULL)

{ p=aux;

if (n < p->info)

aux = p->f_esq;

else

aux = p->f_dir; } if (n == p->info)

printf("%s","Número Repetido");

else if (n < p->info)

p->f_esq=cria_nodo(n, p);

else

p->f_dir=cria_nodo(n, p); } }

void pre_ordem(T_nodo *sub_raiz){ if (sub_raiz != NULL) { printf("%d\n",sub_raiz->info); ordem(sub_raiz->f_esq); ordem(sub_raiz->f_dir); }}

Page 64: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

64

Árvores Binárias de PesquisaÁrvores Binárias de PesquisaT_nodo *consulta(int n)

{ T_nodo *p, *aux;

p=raiz;

aux=raiz;

while (n != p->info && aux != NULL)

{ p=aux;

if (n < p->info)

aux = p->f_esq;

else

aux = p->f_dir;

}

if (n == p->info)

{ printf("Informação Existente");

return(p); } else

{ printf("Informação Inexistente");

getch();

return(NULL); }}

void ordem(T_nodo *sub_raiz)

{ if (sub_raiz != NULL)

{ ordem(sub_raiz->f_esq);

printf("%d\n",sub_raiz->info);

ordem(sub_raiz->f_dir);

}

}

void pos_ordem(T_nodo *sub_raiz)

{ if (sub_raiz != NULL)

{ ordem(sub_raiz->f_esq);

ordem(sub_raiz->f_dir);

printf("%d\n",sub_raiz->info);

}

}

Page 65: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

65

Árvores Binárias de PesquisaÁrvores Binárias de Pesquisa

void retira(int n)

{ T_nodo *aux=raiz, *rem=raiz;

if (raiz == NULL)

{ printf(“Árvore sem elementos");

return();

}

while ((aux != NULL) &&

(n != rem->info))

{ rem = aux;

if (n < rem->info)

aux = rem->f_esq;

else

aux = rem->f_dir;

}

if (n == rem->info)

{ rem->deletado='V';

while ((rem != NULL) && (rem->deletado == 'V'))

{ if (rem->f_esq = NUL) && (rem->f_dir = NUL)

{ if (rem != raiz)

{ aux=rem->pai;

if (aux->f_esq == rem)

aux->f_esq=NULL;

else

aux->f_dir=NULL;

}

else

raiz=NULL;

}

rem=rem->pai;

}

}

else

printf("Elemento não encontrado");

}

Remove logicamente

Remove fisicamente

Remove fisicamente a raiz

ExercícioModificar o programa para que use o campo deletado definido na estrutura da arvore.

Page 66: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

66

Árvores AVLÁrvores AVL• Definição:

– Uma árvore AVL é uma árvore binária de busca construída de tal modo que a altura de sua Sub-árvore direita difere da altura da Sub-árvore esquerda de no máximo 1.

• O que pode acontecer quando um novo nó é inserido numa árvore balanceada ?

• Fator de Balanceamento de um nó:– É a altura da Sub-árvore direita do nó menos a altura da Sub-

árvore esquerda do nó .FB= altura direita - altura esquerda

Se todos os FB forem [-1, 0, 1] a árvore está balanceada.

– Nós 9 ou 11 podem ser inseridos sem balanceamento . Sub-árvore com raiz 10 passa a ter uma Sub-árvore e Sub-árvore com raiz 8 vai ficar melhor balanceada ! – Inserção dos nós 1, 3, 5 ou 7 requerem que a árvore seja rebalanceada!

Page 67: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

67

Árvores AVLÁrvores AVL

• Rebalanceamento: – Nos casos abaixo considere P como sendo o nó raiz de uma Sub-

árvore desbalanceada e U como sendo o nó filho dessa raiz.

– Caso 1: Altura Esquerda de P > Altura Direita de P• Caso 1.1 : Altura Esquerda de U > Altura Direita de U

• Caso 1.2 : Altura Esquerda de U < Altura Direita de U

Rotação a direita

Rotação para a esquerda e em seguida para a direita

Page 68: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

68

Árvores AVLÁrvores AVL

– Caso 2: Altura Direita de P > Altura Esquerda de P• Caso 1.2: Altura Direita de U > Altura Esquerda de U

• Caso 2.2 : Altura Esquerda de U > Altura Direita de U

Rotação a esquerda

Rotação para a direita e em seguida para a esquerda

Page 69: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

69

Árvores AVLÁrvores AVL– Exemplos de Rotações ( Rotação simples a direita):

– Exemplos de Rotações ( Rotação dupla a direita):

Rotação aEsquerda ea Direita

Rotação aDireita

4

2

3 10

6

8

Page 70: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

70

Árvores AVLÁrvores AVL– Exemplos de Rotações (rotação simples a esquerda) :

– Exemplos de Rotações ( Rotação dupla a esquerda):

Rotação aEsquerda

8

4

10

9

15

12

5

10

25

20

30

Inserir 25Inserir 25

5

10

30

25

20

Rotação aDireita ea Esquerda

Page 71: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

71

Árvores AVLÁrvores AVL#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#define true 0

#define false 1

typedef struct nodo

{ int info;

int bal;

struct nodo *f_esq;

struct nodo *f_dir;

int deletado;

}T_nodo;

T_nodo *raiz;

int h;

auxiliar para propagar verificação de Fator de Balanceamento

void mostra_dados(T_nodo *);

T_nodo *cria_nodo(int);

T_nodo *insere_AVL(int, T_nodo *);

T_nodo *caso1(T_nodo *);

T_nodo *caso2(T_nodo *);

T_nodo *rotacao_direita(T_nodo *);

T_nodo *rotacao_esq_dir(T_nodo *);

T_nodo *rotacao_esquerda(T_nodo *);

T_nodo *rotacao_dir_esq(T_nodo *);

void main()

{ int numero=0, achou;

raiz=NULL;

do { printf("Entre com a informação : ");

scanf("%i",&numero);

if (numero != -1)

{ raiz=insere_AVL(numero,raiz);

mostra_dados(raiz); } } while (numero != -1);

}

Page 72: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

72

Árvores AVLÁrvores AVLT_nodo *insere_AVL(int x, T_nodo *pt)

{ if (pt == NULL)

{ pt = cria_nodo(x);

h=true;

}

else

{ if (x < pt->info)

{ pt->f_esq=insere_AVL(x,pt->f_esq);

if (h == true)

{ switch (pt->bal)

{ case 1 : pt->bal = 0;

h=false;

break;

case 0 : pt->bal = -1;

break;

case -1: pt=caso1(pt);

h=false;

break;

}

}

}

Inserção dos Elementos

Recursão Esquerda

Verificar Balanceamento

Interrompe Balanceamento

Ficou com a esquerda maior

Era mais alto a direita, equilibrou

Constata caso1

Page 73: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

73

Árvores AVLÁrvores AVL else

{ if (x > pt->info)

{ pt->f_dir = insere_AVL(x,pt->f_dir);

if (h == true)

{ switch (pt->bal)

{ case -1: pt->bal=0;

h=false;

break;

case 0 : pt->bal=1;

break;

case 1 : pt=caso2(pt);

h=false;

break; } } } else

printf("informação já  existente"); } } return pt;

}

Recursão Direita

Verificar Balanceamento

Era mais alto a esquerda, equilibrou

Ficou com a direita maior

Constata caso2

Page 74: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

74

Árvores AVLÁrvores AVLT_nodo *caso1(T_nodo *pt)

{ T_nodo *ptu;

ptu=pt->f_esq;

if (ptu->bal == -1)

pt=rotacao_direita(pt);

else

pt=rotacao_esq_dir(pt);

pt->bal=0;

return pt;

}

T_nodo *rotacao_direita(T_nodo *pt)

{ T_nodo *ptu;

ptu=pt->f_esq;

pt->f_esq=ptu->f_dir;

ptu->f_dir=pt;

pt->bal=0;

return ptu;

}

T_nodo *caso2(T_nodo *pt)

{ T_nodo *ptu;

ptu=pt->f_dir;

if (ptu->bal == 1)

pt=rotacao_esquerda(pt);

else

pt=rotacao_dir_esq(pt);

pt->bal=0;

return pt;

}

T_nodo *rotacao_esquerda(T_nodo *pt)

{ T_nodo *ptu;

ptu=pt->f_dir;

pt->f_dir=ptu->f_esq;

ptu->f_esq=pt;

pt->bal=0;

return ptu;

}

Caso1.1- sinais iguais e negativos

Caso1.2- sinais diferentes

Caso2.1- sinais iguais e positivos

Caso2.2- sinais diferentes

Page 75: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

75

Árvores AVLÁrvores AVL

T_nodo *rotacao_esq_dir(T_nodo *pt)

{ T_nodo *ptu, *ptv;

ptu=pt->f_esq;

ptv=ptu->f_dir;

ptu->f_dir=ptv->f_esq;

ptv->f_esq=ptu;

pt->f_esq=ptv->f_dir;

ptv->f_dir=pt;

if (ptv->bal == -1)

pt->bal=1;

else

pt->bal=0;

if (ptv->bal == 1)

ptu->bal=-1;

else

ptu->bal=0;

return ptv;

}

T_nodo *rotacao_dir_esq(T_nodo *pt)

{ T_nodo *ptu, *ptv;

ptu=pt->f_dir;

ptv=ptu->f_esq;

ptu->f_esq=ptv->f_dir;

ptv->f_dir=ptu;

pt->f_dir=ptv->f_esq;

ptv->f_esq=pt;

if (ptv->bal == 1)

pt->bal=-1;

else

pt->bal=0;

if (ptu->bal == -1)

ptu->bal=1;

else

ptu->bal=0;

return ptv;

}

Page 76: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

76

Árvores AVLÁrvores AVLvoid mostra_dados(T_nodo *sub_raiz)

{ if (sub_raiz != NULL)

{ mostra_dados(sub_raiz->f_esq);

mostra_dados(sub_raiz->f_dir);

printf("\n%d",sub_raiz->info);

}

}

T_nodo *cria_nodo(int n)

{ T_nodo *novo;

novo=(T_nodo *) malloc(sizeof(struct nodo));

if (novo == NULL)

{ printf("Memória insuficiente");

exit(1);

}

novo->info=n;

novo->bal=0;

novo->f_esq=NULL;

novo->f_dir=NULL;

novo->deletado='f';

return(novo);

}

função recursiva para percorrer a árvore. Baseada na função pós-ordem

Page 77: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

77

Árvores - BÁrvores - B• Definição:

– É a Construção e manutenção de árvores de busca de grandes dimensões.

– Ponteiros referem-se a áreas de memória secundária, em vez de representarem endereços da memória principal.

– Busca: acesso a disco (com os inerentes atrasos de acesso).– Sub-árvores representadas em unidades, do ponto de vista de

acesso páginas

– Reduz o número de acessos ao disco.– Necessita de esquema de crescimento controlado.– Todo nó, exceto a raiz, deve possuir entre n e 2n chaves, para uma

dada constante n.

• Características: – Cada página (nó) contém no máximo, 2n elementos (chaves);– cada página, exceto a que contém a raiz, contém no mínimo n

chaves;– os nós chamados folhas não têm descendentes e os demais(nós de

derivação) possuem m + 1 descendentes, onde m é a quantidade de chaves;

– todas as folhas têm o mesmo nível.

Page 78: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

78

Árvores - BÁrvores - B

• Representação Estrutural:

• Exemplo: Árvore B (ordem 2):

K1 K2 ... KmP0 P1 P2 ... Pm-1 Pm

30

15 22 40 50

17 18 20 212 6 8 9 27 29 36 38 39 42 45 48 51 53 55 56

Raiz

Page 79: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

79

Árvores – B : OperaçõesÁrvores – B : Operações• Inserção:

• Algoritmo Simplificado de Pesquisa:

x - argumento de pesquisaKi - valores das chaves dos nós de derivação

(i) Se Ki < x < Ki+1; seguir Pi

(ii) Se x < K1; seguir P0

(iii) Se x > Km; o caminho será indicado por Pm

20

7 10 15 18 26 30 35 40

20 30

7 10 15 18 35 4022 26

Inserção da chave 22

K1 K2 ... KmP0 P1 P2 ... Pm-1 Pm

Page 80: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

80

Árvores – B : OperaçõesÁrvores – B : Operações• Inserção – 3 etapas:

(i) localizar a folha apropriada a partir da raiz;(ii) Se o registro encontra lugar em um nó folha não

completamente preenchido =>PROCESSO LIMITADO ÀQUELE NÓ

(iii) NÓ COMPLETO => PARTIÇÃO (criação de um novo nó), podendo se propagar até a RAIZ aumentando a altura da árvore.

• Algoritmo Simplificado:

INSERE( chave, no) Localizar lugar de inclusão; Se (nó cheio) então Criar novo nó; Divide nó cheio; INSERE (chave-do-meio, nó-de-cima); Senão Coloca chave no nó; Ajusta ponteiros; fim-se;fim.

Page 81: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

81

Árvores – B : OperaçõesÁrvores – B : Operações• Retirada: A chave a ser retirada pode residir no nó folha ou num nó de

derivação.

• Exemplo:

• Algoritmo Simplificado:

REMOVE( x, no) Se (x está no nó folha) então

Retira x; Se (restaram n-1 chaves) então Se (vizinho possui m>n chaves) então Empresta chave do vizinho; Desce chave separadora do nó ascendente substituindo pela emprestada; Senão Concatena nó com o vizinho; Desce chave do meio do nó ascendente; fim-se fim-seSenão Substitui x por adjacente; REMOVE(adjacente, no);

fim-sefim.

20 60

5 15 70 80 90

Remoção da chave 60

30 40 50 5 15 80 9030 40 50

20 70

Page 82: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

82

Árvores – B: Implementação em CÁrvores – B: Implementação em CPesquisa (Registro *x, Ponteiro Ptr){ int i;

if (Ptr == NULL) { printf("Registro não esta presente na arvore \n");

return;}i = 1;while (i < Ptr -> n) && (x -> Chave > Ptr -> r[i-1].chave)

i++;if (x -> chave == Ptr -> r[i-1].chave) { *x == Ptr -> r[i-1];

return;}if (x -> chave < Ptr -> r[i-1].chave)

Pesquisa(x, Ptr -> p[i-1]);else

Pesquisa(x, Ptr -> p[i]);

} /* Pesquisa */

typedef struct {TipoChave Chave;/* - outros componentes - */

} Registro;

typedef struct Página_st *Ponteiro;

typedef struct Página_str {int n;Registro r[mm];Ponteiro p[mm + 1];

} Página;

Page 83: Ciência da Computação Estrutura de Dados I Professores: Artur Henrique Kronbauer José Maria David Maria Luiza Braga 1.

83

Árvores Graduadas e Rubro-NegrasÁrvores Graduadas e Rubro-Negras• Definições:

– Uma árvore binária de busca é graduada quando, para todo nó v (Szwarcfiter e Markenzon, 1994):

• (i) posto(v) = 0, se v é um nó externo;• (ii) posto(v) = 1, se v é pai de nó externo;• (iii) posto(v) < posto(w) < posto(v)+ 1, se w é pai de v;• (iv) posto(v) < posto(w), se v possui avô w.

– Uma árvore binária de busca é rubro-negra quando, para todo nó v existe uma coloração tal que (Szwarcfiter e Markenzon, 1994):

• (i) se v é um nó externo, v é negro;• (ii) os caminhos de v para os seus descendentes nós

externos possuem o mesmo número de nós negros;• (iii) se v (não raiz) é um nó rubro então seu pai, w, é um nó

negro.