estrutura de dados -...

Post on 01-Feb-2018

226 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Estrutura de Dados Carlos Eduardo Batista

Centro de Informática - UFPB

bidu@ci.ufpb.br

Estruturas de Dados

Listas e Filas

2

Estrututuras de dados lineares

Pilhas

Pilhas (stack)

Estrutura de dados onde a inserção e remoção de elementos ocorre a partir de uma único ponto de interação – o topo da pilha

LIFO ◦ Last In First Out

Exemplos ◦ Pilha de pratos a lavar

◦ Pilha de execução na linguagem C

Variáveis locais são empilhadas em uma pilha

Ao término da função, as variáveis são desempilhadas

4

Pilhas

Operações ◦ Empilhar (push)

Insere um novo elemento no topo da pilha

◦ Desempilhar (pop)

Recupera e remove um elemento do topo da pilha

5

Listas 6

Lista sequencial

Lista encadeada

Listas

Lista sequencial ◦ Acesso a qualquer elemento em tempo constante

◦ Movimentação e inserção custosa

◦ Tamanho máximo definido

◦ Ideal para:

Listas de tamanho conhecido (pequenas), inserção remoção no fim

7

Listas

Lista encadeada ◦ Não precisa deslocar elementos nas operações de inserção e remoção

◦ Crescimento em tempo de execução

◦ Limite é a memória disponível

◦ Acesso a elementos, porém, requer busca prévia

◦ Ideal para:

Listas grandes, inserção/remoção no meio, sem tamanho máximo definido

8

Listas encadeadas

Ponteiros

9

typedef struct no {

t_elemento dado; // elemento contendo os dados

struct no * prox; // ponteiro para o proximo elemento

} t_no; // tipo da estrutura

t_no * p;

Listas encadeadas 10

free(P);

P = NULL;

Lista encadeada 11

// Tipo base dos elementos da lista

typedef struct elementos {

char nome[50];

// Outros elementos

} t_elemento;

// Estrutura lista

typedef struct no {

t_elemento dado; // elemento contendo os dados

struct no * prox; // ponteiro para o proximo elemento

} t_no; // tipo da estrutura

// define t_lista como sendo um outro nome para "t_no *"

typedef t_no* t_lista;

12

t_no * criaNo() {

t_no * no = (t_no*) malloc(sizeof(t_no));

if (no)

no->prox = NULL;

return no;

}

int isVazia(t_lista lista) {

return (lista == NULL);

}

int getTamanho(t_lista lista) {

int n = 0;

while (lista != NULL) {

lista = lista->prox;

n++;

}

return n;

}

Lista encadeada 13

t_no * getNo(t_lista lista, int pos) {

int n = 0;

if (pos<0)

return 0;

while (lista != NULL) {

if (n==pos)

return lista;

lista = lista->prox;

n++;

}

return 0;

}

Lista encadeada 14

t_elemento * getElemento(t_lista lista, int pos)

{

t_no * no = getNo(lista, pos);

if (no != NULL)

return &(no->dado);

else

return NULL;

}

Lista encadeada 15

int getPosicao(t_lista lista, t_elemento dado) {

int n = 0;

while (lista != NULL) {

if (compara(lista->dado, dado)==0)

return n;

lista = lista->prox;

n++;

}

return -1;

}

int compara(t_elemento dado1, t_elemento dado2) {

return strcmp(dado1.nome, dado2.nome);

}

Lista encadeada: implementação

16

int inserir(t_lista *lista, int pos, t_elemento dado) {

t_no * p, * novo;

if (pos == 0) {

novo = criaNo();

if (novo == NULL)

return 0;

novo->dado = dado;

novo->prox = *lista;

*lista = novo;

return 1;

}

p = getNo(*lista, pos-1);

if (p == NULL)

return 0;

novo = criaNo();

if (novo == NULL)

return 0;

novo->dado = dado;

novo->prox = p->prox;

p->prox = novo;

return 1;

}

Lista encadeada 17

int remover(t_lista *lista, int pos) {

t_no *anterior, *p;

if (isVazia(*lista)) return 0; // erro: lista vazia

if (pos<0) return 0; // erro: posicao invalida

// remocao da primeira posicao em lista nao vazia

if (pos == 0) {

p = *lista;

*lista = p->prox;

} else { // remocao em qualquer posicao

anterior = getNo(*lista, pos-1);

if (anterior == NULL)

return 0; // erro: posicao invalida

p = anterior->prox;

if (p == NULL)

return 0; // erro: posicao invalida

anterior->prox = p->prox;

}

free(p);

return 1;

}

Listas

Distribuição na memória ◦ Sequencial

◦ Encadeada

Tamanho ◦ Estática

◦ Dinâmica

Ordenamento ◦ Ordenada

◦ Desordenada

18

Listas ordenadas

Implementação sequencial ou encadeada

Nós ordenados de acordo com os dados que possuem e uma lógica de ordenação

Complexidade de implementação comparável com as não ordenadas

Diferente apenas na operação de inserção ◦ Não é necessário passar a posição de inserção

◦ É efetuada uma busca pela posição correta

19

Lista encadeada ordenada 20

int getPosicaoInsercaoOrdenada(t_lista lista, t_elemento dado)

{

int n = 0;

while (lista != NULL) {

if (compara(lista->dado, dado)>=0)

return n;

lista = lista->prox;

n++;

}

// lista vazia, ou nao achou elemento, retorna posicao zero

return n;

}

Listas encadeadas

Listas circulares

21

Listas circulares

Último elemento aponta para o primeiro, e não mais para NULL

É possível atingir qualquer elemento da lista a partir de qualquer nó.

Convencionalmente utiliza-se como ponteiro para a lista um ponteiro para o último elemento. ◦ Tem-se acesso direto ao “último” e “primeiro” elemento.

22

Lista encadeada 23

Lista duplamente encadeada

Lista circular duplamente encadeada

Lista duplamente encadeada 24

// Tipo base dos elementos da lista

typedef struct elementos {

char nome[50];

} t_elemento;

// Estrutura lista

typedef struct no {

struct no * anterior; // ponteiro para o proximo elemento

t_elemento dado; // elemento contendo os dados

struct no * prox; // ponteiro para o proximo elemento

} t_no; // tipo da estrutura

Lista duplamente encadeada

É possível percorrer a lista em ordem inversa

O nó atual acessa o antecessor e o sucessor

Último e primeiro nós são equivalentes

Desvantagem: Mais memória com o ponteiro extra

25

Filas

Conjunto de itens onde o acesso a elementos é feito em uma extremidade (início da fila) e as inserções de elementos são realizadas na outra extremidade (final da fila)

First in, first out (FIFO) Lista linear em que a inserção é feita

numa extremidade e a eliminação na outra.

26

Filas

Fila de um banco Fila do cinema Fila de atendimento

◦ Quem primeiro entrar na fila, é o primeiro a ser atendido (a sair da fila).

Grupo de carros esperando sua vez para passar no pedágio

Gerenciador de impressão num ambiente multiusuário (impressora compartilhada)

Escalonamento de tarefas: fila de processos aguardando os recursos do sistema operacional.

Fila de pacotes a serem transmitidos numa rede de computadores

27

Filas

Implementação ◦ Realizada a partir de uma lista com duas cabeças (ponteiros).

◦ A implementação encadeada dinâmica torna mais simples as operações de inserção e remoção.

◦ Já a implementação sequencial é um pouco mais complexa, mas pode ser usada quando há previsão do tamanho máximo da fila.

28

Filas

Fila sequencial ◦ Um vetor de elementos

◦ Um campo para controlar o início da fila

◦ Outro campo para controlar o final da fila

29

Filas 30

Filas

Existem mais dois elementos livres na fila, mas nenhum outro elemento pode ser inserido

Fila.final chegou à condição de limite (MAX -1)

Podemos chegar à situação absurda em que a fila está vazia, mas nenhum elemento novo pode ser inserido

A representação sequencial descrita anteriormente não é adequada

31

Filas

Problemas… Existem mais dois elementos livres na fila,

mas nenhum outro elemento pode ser inserido

Fila.final chegou à condição de limite (MAX -1)

Podemos chegar à situação absurda em que a fila está vazia, mas nenhum elemento novo pode ser inserido.

Conclusão: A representação sequencial descrita anteriormente não é adequada!

32

Fila circular 33

Forçar final a usar o espaço liberado na frente

Para permitir a reutilização das posições já ocupadas, usa-se o conceito de Fila Circular

x x x x x

fim inicio

Fila circular

Fila cheia?

Quando o fim == (inicio-1) ou

Se o inicio for zero?

Quando o fim == (MAX-1);

O ponteiro do fim não pode passar pelo do inicio;

34

x x x x x

fim inicio

Filas - Implementação

Operações ◦ Criar fila

◦ Verificar se fila está vazia

◦ Verificar se fila está cheia

◦ Inserir item na fila

◦ Remover item da fila

◦ Exibir fila

◦ Esvaziar fila

35

Fila sequencial 36

// tamanho maximo da fila

#define MAX 5

// Tipo base dos elementos da fila

typedef struct elementos {

char nome[50];

} t_elemento;

typedef struct fila {

t_elemento vetor[MAX]; // vetor que armazena a fila

int inicio; // posicao do primeiro elemento

int fim; // posicao do ultimo elemento

int quant_element; // numero de elementos da fila

} t_fila;

Fila sequencial 37

t_fila criar()

{

t_fila fila;

fila.inicio = 0;

fila.fim = -1;

fila.quant_element = 0;

return fila;

}

int isVazia (t_fila * fila)

{

return (fila->quant_element == 0);

}

int isCheia(t_fila * fila)

{

return (fila->quant_element == MAX);

}

Fila sequencial 38

int inserir (t_fila * fila, t_elemento valor)

{

if (isCheia(fila))

return 0;

(fila->quant_element)++;

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

fila->vetor[fila->fim] = valor;

return 1;

}

t_elemento remover(t_fila * fila)

{

t_elemento valor = { "" } ;

if (isVazia(fila))

return valor; // Erro: fila vazia

valor = fila->vetor[fila->inicio];

fila->vetor[fila->inicio].nome[0] = '\0';// zera, opcional

(fila->quant_element)--;

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

return valor;

}

Fila sequencial 39

void exibir(t_fila * fila) {

int i;

if (isVazia(fila)) {

printf("Fila vazia\n");

return;

}

printf("\nExibindo fila:\n");

printf("inicio: %d\n", fila->inicio);

printf("fim: %d\n", fila->fim);

for (i=0 ; i<MAX ; i++) {

printf("%d::%s\n", i, fila->vetor[i].nome);

}

}

Fila encadeada

Lista simplesmente encadeada “especial”

Para remover da fila, implementa-se uma função que retira sempre do início

Para inserir na fila, implementa-se uma função que acrescenta sempre no final

40

Fila encadeada

Lista simplesmente encadeada – Desvantagem: Para cada elemento inserido na fila, teremos

que percorrer todos os nós até encontrar o último. Não é interessante

Lista simplesmente encadeada com dois ponteiros;

–Desvantagem: ter dois ponteiros Lista simplesmente encadeada circular

–Único ponteiro para o final da fila Lista simplesmente encadeada com cabeça especial.

–Um único ponteiro para a cabeça especial, e, essa cabeça é que tem o ponteiro para o inicio e o fim

41

Fila encadeada

Características ◦ Ponteiro para o primeiro nó;

◦ Ponteiro para o último nó;

◦ Informação sobre a quantidade de elementos da lista.

42

Fila encadeada

Operações ◦ Criar fila

◦ Verificar se fila está vazia

◦ Inserir item na fila

◦ Remover item da fila

◦ Exibir fila

◦ Esvaziar fila

43

Fila encadeada 44

// Tipo base dos elementos da lista

typedef struct elementos {

char nome[50];

} t_elemento;

typedef struct no {

t_elemento dado;

struct no * prox;

} t_no;

typedef struct fila {

t_no* inicio;

int quant_element;

t_no* final;

} t_fila;

Fila encadeada 45

t_fila * criaCabeca ()

{

t_fila * fila = (t_fila*) malloc(sizeof(t_fila));

if (fila) {

fila->inicio = fila->final = NULL;

fila->quant_element=0;

}

return fila;

}

t_no * criaNo() {

t_no * no = (t_no*) malloc(sizeof(t_no));

// verifica se houve memoria suficiente para alocar

if (no)

no->prox = NULL;

return no;

}

Fila encadeada 46

int isVazia (t_fila * fila)

{

return (fila->quant_element == 0);

}

int inserir (t_fila *fila, t_elemento valor) {

t_no *novo;

novo = criaNo();

if (novo == NULL)

return 0; // Erro: memoria insuficiente

novo->dado = valor;

if (isVazia(fila))

fila->inicio = novo;

else

(fila->final)->prox = novo;

fila->final = novo;

fila->quant_element++;

return 1;

}

Fila encadeada 47

t_elemento remover (t_fila *fila)

{

t_no *aux;

t_elemento valor = { "" } ;

if (isVazia(fila))

return valor; // Erro: fila vazia

valor = (fila->inicio)->dado;

if (fila->inicio == fila->final)

fila->final = NULL;

aux = fila->inicio;

fila->inicio = (fila->inicio)->prox;

free(aux);

fila->quant_element--;

return valor;

}

Fila de prioridade

Filas de prioridade – A fila fica ordenada por ordem de prioridade.

– A operação de inserção não insere somente no final, pode ser em qualquer posição obedecendo a ordem de prioridade.

– A operação de remoção remove sempre o primeiro elemento.

– Implementação:

• Remoção rápida: O(1)

• Inserção lenta: O(n), ou O(log n). Depende da implementação. Para atingir O(log n) teria que ser implementada usando árvores na implementação encadeada; ou busca binária na implementação sequencial.

48

Próximas aulas

Estruturas de dados não lineares

49

Referências

Notas de Aula do Prof. Bruno B. Boniati

Notas de Aula do Prof. João Luís Garcia Rosa

Notas de Aula do Prof. Derzu Omaia

50

Estrutura de Dados Carlos Eduardo Batista

Centro de Informática - UFPB

bidu@ci.ufpb.br

top related