11.3.4 – Encadeamento circular

No encadeamento apresentado, seja p um ponteiro apontando
para um determinado nó
p

Com sucessivas execuções do comando p = p->prox;
pode-se percorrer a lista

Mas, com esse comando não se chega a nós anteriores
Lista encadeada circular:

O ponteiro do último nó aponta para o nó-líder, ao invés de
apontar para NULL

Para determinadas aplicações, os conceitos de primeiro,
segundo, ... e último elementos da lista não têm relevância

Então pode-se eliminar o nó-líder, sendo um ponteiro para
qualquer nó do encadeamento suficiente para identificar a
lista
11.3.5 – Listas duplamente encadeadas

Há aplicações de listas lineares que exigem frequentes
percursos nos dois sentidos

Pode-se acrescentar a cada nó mais um campo do tipo
ponteiro (prev), com a finalidade de apontar para o nó
anterior no encadeamento

Declarações:
typedef char nome[16];
typedef struct noh noh;
typedef noh *lista;
typedef noh *posicao;
struct noh {
nome elem; noh *prev, *prox;
};

Inserção de um nó na posição p:
p
Nó a ser
inserido

Remoção do um nó da posição p:
Nó a ser
removido
p
Exercícios 11.3:
1. Escrever um subprograma que receba como argumentos uma
lista linear L encadeada por ponteiros e que elimine dessa lista os
elementos em duplicata. Escrever também um programa principal
para testar devidamente essa função
2. Escrever um subprograma que receba como argumentos dois
ponteiros L1 e L2, apontando cada um para um encadeamento
distinto de estruturas, ambos iniciados por um nó-líder, e que
efetue uma troca de estruturas nesses encadeamentos. No
encadeamento de L1 devem ficar todas as estruturas cujos
elementos guardados sejam números ímpares e no encadeamento
de L2 aquelas contendo números pares.
Esse subprograma não deve alocar nenhuma nova estrutura, nem
deixar nenhuma estrutura já existente fora dos encadeamentos,
nem trocar o valor guardado em nenhuma estrutura.
Escrever um programa principal para testar devidamente o referido
subprograma
3.
Escrever um subprograma que receba como argumento uma lista L
encadeada circular sem nó-líder e que inverta seu encadeamento,
conforme apresentado na figura abaixo
Importante: o subprograma não deve deletar, nem criar qualquer nó,
nem mudar o conteúdo de nenhum nó.
Escrever um programa principal para testar devidamente o referido
subprograma.
Capítulo XI – Noções de
Estruturas de Dados
11.1 – Importância de boa estruturação de
informações
11.2 – Modelos de armazenamento de informações
11.3 – Listas lineares encadeadas
11.4 – Pilhas e filas
11.5 – Árvores
11.4 – Pilhas e Filas
11.4.1 – Listas lineares com disciplina de acesso

As listas lineares gerais admitem inserção e remoção de
elementos em qualquer posição

Existem listas lineares especiais que admitem inserção e
remoção somente em suas duas extremidades

São elas as pilhas, as filas e os deques

Pilhas: inserção e remoção em apenas uma das extremidades

Filas: inserção numa extremidade e remoção na outra

Deques: as duas operações nas duas extremidades
11.4.2 – Pilhas

O último a entrar é o primeiro a sair (LIFO – last in first
out)
Podem usar
estrutura contígua
e encadeada
A seguir, uma
representação
gráfica da
estrutura
encadeada
Estrutura encadeada para pilhas:
Declarações:
typedef struct noh noh;
typedef noh *pilha;
struct noh {
int elem; noh *prox;
};
pilha P;
Operações típicas:
Empilhar um elemento
Desempilhar o elemento do
topo
Copiar o elemento do topo
Esvaziar
Verificar se está vazia
Utilidade de pilhas:

Cálculo de expressões

Gerenciamento da área de dados das funções na execução de
um programa

Algoritmos para árvores e grafos

Eliminação de recursividade
11.4.3 – Filas

O primeiro a entrar é o primeiro a sair (FIFO – first in first
out)

Podem usar estrutura contígua e encadeada

A seguir, uma representação gráfica da estrutura encadeada
Estrutura encadeada para filas:
Declarações:
typedef struct noh noh;
typedef struct fila fila;
struct noh
{int elem; noh *prox;};
struct fila {noh *fr, *tr;};
fila F;
Operações típicas:
Entrar com um elemento
Remover o elemento da
frente
Copiar o elemento da frente
Esvaziar
Verificar se está vazia
Utilidade de filas:

Gerenciamento da utilização de recursos computacionais pelo
sistema operacional

Software de controle de saída e chegada de aeronaves em
aeroportos

Algoritmos para árvores e grafos

Circuitos eletrônicos
Capítulo XI – Noções de
Estruturas de Dados
11.1 – Importância de boa estruturação de
informações
11.2 – Modelos de armazenamento de informações
11.3 – Listas lineares encadeadas
11.4 – Pilhas e filas
11.5 – Árvores
11.5 – Árvores
11.5.1 – Definições
Forma natural de
apresentação

Cada elemento é armazenado em um nó

Sobre os nós existe uma hierarquia paterna

Entre alguns pares, existe a relação “pai de”
A é pai de B, C e D
D é pai de H
C é pai de F e G
etc.

Raiz: nó de máxima hierarquia de uma árvore

Abaixo, A é a raiz

Cada nó tem um e apenas um pai (exceto a raiz)

Cada nó tem zero ou mais filhos

Um nó não pode ter um ancestral como filho
Exemplo: I não pode ser
pai de H, D ou A
Definição recursiva de Árvore:

Um único nó é por si mesmo uma árvore; ele é a raiz dessa
árvore

Sejam A1, A2, ... , Ak, árvores de raízes n1, n2, ..., nk,
respectivamente e n um nó não pertencente a nenhuma delas
 Fazendo n pai de n1, n2, ..., nk, obtém-se uma nova árvore
n
n1
A1
n2
A2
nk
n3
A3
Ak
Mostrar que a seguinte figura é uma árvore:
A
B
E
C
F
D
G
H
I
J
K

I, J e K são por si só árvores; fazendo H pai das raízes I, J e
K, obtém-se nova árvore

F, G e E são por si só árvores; fazendo B pai de E, C pai de F
e G, e D pai de H, obtém-se novas árvores
A
B
E

C
F
Fazendo A pai de B, C e D,
obtém-se nova árvore
D
G
H
I
J
K

Folha: nó sem filhos; abaixo, E, F, G, I, J e K são folhas

Irmãos: filhos de um mesmo nó; abaixo:
B, C e D são irmãos; F e G são irmãos; I, J e K são irmãos

Floresta: conjunto de zero ou mais árvores disjuntas
Forma parentética: forma de representar uma árvore em que
cada elemento é um caractere

Coloca-se entre parêntesis: primeiramente a raiz, depois as
formas parentéticas das sub-árvores da raiz ordenadas da
esquerda para a direita (recursividade):
(A (B (E)) (C (F) (G)) (D (H (I) (J) (K))) )
Forma parentética: definição recursiva
1. Sendo c um caractere genérico, (c) é uma forma parentética
correta
2. Se α1, α2, α3, ... αn, são formas parentéticas corretas
(n > 0), então (c α1α2α3 ... αn) também é
Ordenação ou caminhamento em pré-ordem: é uma forma
de ordenar todos os nós de uma árvore




Primeiramente aparece a raiz n
Seguida dos nós de A1 em pré-ordem
Seguidos dos nós de A2 em pré-ordem, etc.
Até os nós de Ak em pré-ordem
É também uma
definição recursiva
n
n1
A1
n2
A2
nk
n3
A3
Ak
Exemplo: pré-ordem da árvore abaixo:
A B E C F G D H I J K
11.5.2 – Estruturas de dados para árvores

Uma árvore também pode ser armazenada num vetor ou num
encadeamento de estruturas

Seja a árvore já vista:
A) Estrutura contígua (vetor)

Nós são índices do vetor

Os nós estão em pré-ordem
Declarações:
typedef int noh;
typedef struct celula celula;
typedef struct arvore arvore;
struct celula {char info; int nfilhos, pai;}
struct arvore {celula Espaco[100]; int nnos;}
noh n1, n2, n3;
Nesta estrutura, os algoritmos
arvore A1, A2, A3;
são geralmente ineficientes
B) Estrutura com encadeamento de pais e irmãos
Declarações:
info pai
typedef struct celula celula;
celula
typedef celula *noh;
fesq idir
typedef celula *arvore;
struct celula {char informacao; noh pai, fesq, idir;};
noh n1, n2, n3;
arvore A1, A2, A3;

Nós são ponteiros para
células

Para ilustrar, a seguir,
comandos para construir
a árvore ao lado
arvore A; noh x, y;
A = (noh) malloc (sizeof (celula));
A->info = 'A'; A->pai = A->idir = NULL;
A->fesq = (noh) malloc (sizeof (celula));
x = A->fesq;
x->info = 'B'; x->pai = A;
x->fesq = (noh) malloc (sizeof (celula));
x->idir = (noh) malloc (sizeof (celula));
x->fesq->info = 'E';
x->fesq->pai = x;
x->fesq->fesq = x->fesq->idir = NULL;
x = x->idir;
x->info = 'C';
x->pai = A;
x
x->idir = NULL;
x->fesq = (noh) malloc (sizeof (celula));
y = x->fesq;
E
y->info = 'F';
y->pai = x;

y->fesq = NULL;
y->idir = (noh) malloc (sizeof (celula));
y->idir->info = 'G';
y->idir->pai = x;
y->idir->fesq = y->idir->idir = NULL;
A

A

B
C
x


F
G


y
x
y

Os comandos anteriores
formam apenas esta árvore
em particular
A

A

Em CES-11 serão vistos
algoritmos gerais de
formação de árvores
B
C

E


F
G



Download

CES-10 Teoria Cap 11-c