You are on page 1of 131

Ponteiros em Pascal

Variáveis ponteiros são aquelas que guardam o endereço de outra, possibilitando o acesso a seu conteúdo. Declaração em Pascal:
 var ptInt: ^integer; {ponteiro para uma variável inteira } ptReal: ^real; {ponteiro para uma variável real}
1

Operador @ Operador unário que retorna o endereço de uma variável
program soma; var S,A,B:integer; PtS,PtA,PtB : ^integer; begin readln(A,B); PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; writeln('Resultado: ',PtS^); end.
2

Alocação de memória
program soma; var S,A,B: integer; PtS,PtA,PtB: ^integer; begin → A := 2; B := 3; PtA := @A; PtB := @B; PtS := @S; PtS^ := PtA^ + PtB^; Writeln('Resultado: ',PtS^); end.

PtA

PtB

PtS

A

B

S

3

var S. begin A := 2. PtB := @B. PtS^ := PtA^ + PtB^. end. PtA PtB PtS A 2 B S 4 .Alocação de memória program soma. PtS. PtS := @S. → B := 3.PtA.PtS^). PtA := @A. Writeln('Resultado: '.B: integer.A.PtB: ^integer.

PtA PtB PtS A 2 B 3 S 5 .PtS^).PtB: ^integer.Alocação de memória program soma. PtB := @B. B := 3. var S. begin A := 2.A. Writeln('Resultado: '.B: integer. PtS := @S.PtA. → PtA := @A. PtS^ := PtA^ + PtB^. PtS. end.

PtS := @S. end. var S.PtA.PtS^). begin A := 2. Writeln('Resultado: '.B: integer. PtA := @A.Alocação de memória program soma. B := 3.A. PtS.PtB: ^integer. → PtB := @B. PtA PtB PtS A 2 B 3 S 6 . PtS^ := PtA^ + PtB^.

begin A := 2. → PtS := @S. var S. PtA := @A.B: integer.A. PtB := @B. Writeln('Resultado: '. PtA PtB PtS A 2 B 3 S 7 .PtA. PtS^ := PtA^ + PtB^.PtB: ^integer.Alocação de memória program soma. B := 3.PtS^). end. PtS.

PtB := @B.B: integer. end.A. Writeln('Resultado: '.Alocação de memória program soma. PtS := @S. begin A := 2.PtS^). var S. → PtS^ := PtA^ + PtB^.PtA. PtS. B := 3.PtB: ^integer. PtA := @A. PtA PtB PtS A 2 B 3 S 8 .

→ Writeln('Resultado: '.Alocação de memória program soma.A.PtA. B := 3.B: integer. PtA PtB PtS A 2 B 3 S 5 9 .PtB: ^integer. PtB := @B. PtA := @A. var S. PtS^ := PtA^ + PtB^. PtS := @S. PtS. begin A := 2. end.PtS^).

B: integer. PtA := @A. end. 5 PtA PtB PtS A 2 B 3 S 5 10 .Alocação de memória program soma. PtS^ := PtA^ + PtB^. var S. PtS := @S.PtS^).PtA. PtB := @B. B := 3. begin A := 2. Writeln('Resultado: '.A.PtB: ^integer. PtS.

P^ := 'Bom dia!'.procedure New( ) Cria dinamicamente (em tempo de execução) uma nova variável e faz uma variável ponteiro apontar para ela. begin New(P). end. 11 . Writeln (P^) Dispose(P). var P: ^Str18. type Str18 = string[18].

Writeln (P^) Dispose(P).Alocação de memória type Str18 = string[18]. var P: ^Str18. P 12 . end. begin → New(P). P^ := 'Bom dia!'.

var P: ^Str18. Writeln (P^) Dispose(P). → P^ := 'Bom dia!'.Alocação de memória type Str18 = string[18]. begin New(P). P 13 . end.

end. → Writeln (P^) Dispose(P). begin New(P). P^ := 'Bom dia!'. P Bom Dia! 14 . var P: ^Str18.Alocação de memória type Str18 = string[18].

P Bom Dia! 15 . var P: ^Str18.Alocação de memória Bom Dia! type Str18 = string[18]. begin New(P). end. Writeln (P^) → Dispose(P). P^ := 'Bom dia!'.

var P: ^Str18. Writeln (P^) Dispose(P). end. 16 . begin New(P). P OBS: a procedure Dispose libera uma variável criada dinamicamente.Alocação de memória type Str18 = string[18]. para que o SO possa reutilizar o espaço de memória correspondente. P^ := 'Bom dia!'.

.Um ponteiro recebendo o valor de um outro.. Ex: q:= p. Quando isso acontece. U m ponteiro recebe o valor de um outro através do comando de atribuição.. ele passa a apontar para o mesmo objeto que o outro aponta 17 ..

new(q).{ou q^ ou r^ } dispose(q).Alocação de memória var p.q. begin → new(p). p^ := 5. r := p.r: ^integer. q:= p.{ou p ou r } : p q r 18 . {ou q} writeln(p^).

{ou p ou r } : p q r 19 .q. begin new(p).r: ^integer.Alocação de memória var p. r := p.{ou q^ ou r^ } dispose(q). q:= p. new(q). → p^ := 5. {ou q} writeln(p^).

r := p.r: ^integer. q:= p.Alocação de memória var p. {ou q} writeln(p^).{ou q^ ou r^ } dispose(q). p^ := 5. → new(q). begin new(p).{ou p ou r } : p q r 5 20 .q.

q.r: ^integer. p^ := 5. r := p.{ou q^ ou r^ } dispose(q).{ou p ou r } : p q r 5 21 . → q:= p. begin new(p).Alocação de memória var p. new(q). {ou q} writeln(p^).

→ r := p. q:= p. p^ := 5. new(q).q. begin new(p).{ou q^ ou r^ } dispose(q).r: ^integer. {ou q} writeln(p^).{ou p ou r } : p q r 5 22 .Alocação de memória var p.

Alocação de memória var p. {ou q} → writeln(p^). begin new(p). p^ := 5. r := p.q.r: ^integer. new(q).{ou p ou r } : p q r 5 23 .{ou q^ ou r^ } dispose(q). q:= p.

begin new(p). p^ := 5.{ou p ou r } : p q r 5 24 .r: ^integer. {ou q} writeln(p^). q:= p. r := p.q.Alocação de memória 5 var p. new(q).{ou q^ ou r^ } → dispose(q).

begin new(p).Alocação de memória var p. new(q).r: ^integer. {ou q} writeln(p^). p^ := 5.{ou q^ ou r^ } dispose(q). r := p.{ou p ou r } : → p q r 25 .q. q:= p.

q... new(q). Portanto. {ou q} writeln(p^).r: ^integer. p. o manuseio de ponteiros begin exige cuidado! new(p).{ou q^ ou r^ } dispose(q). r := p..Alocação de memória ATENÇÃO: observe que a partir de q:=p. p r q q:= p. perdeu-se o acesso à variável criada com var new(q).{ou p ou r } : → 26 . p^ := 5.

Estratégias: • Empregar um agregado homogêneo (array) superdimensionado.... / 27 . N-1 N • Empregar seqüências de células (nós) que contêm dois elementos: um valor e um ponteiro para o próximo nó. p . 1 2 3 ..Listas lineares Em várias situações em programação temos que lidar com listas de elementos cujo tamanho exato é desconhecido.

.Quando adotar uma ou outra solução? • Agregado homogêneo: quando pudermos determinar com segurança o tamanho máximo. • Listas encadeada: . e/ou.quando se desejar maior agilidade nas inclusões ou exclusões de novos elementos.quando for difícil estimar o tamanho máximo com segurança. .. 28 .

. Lista vazia / p 4 Um inteiro seguido de uma lista de inteiros.Lista: uma estrutura recursiva: Ex: definição de uma lista de inteiros: • Lista vazia. • Um inteiro seguido de uma lista de inteiros.. p 7 1 9 / 29 .

. Lista vazia / p Um inteiro seguido de uma lista de inteiros. p 4 7 1 9 / 30 .. primeiro nó aponta para a lista formada pelos demais nós lista de • Um inteiro seguido de uma inteiros.Lista: uma estrutura recursiva: Ex: definição de uma lista de inteiros: O ponteiro contido no • Lista vazia.

é necessário que haja sempre uma • Lista variável apontando para a “cabeça” da • Um inteiro seguido de uma lista de lista. inteiros..Lista: uma estrutura recursiva: Ex: definição de uma lista de inteiros: OBS: para se ter acesso aos elementos da lista vazia.. p 4 7 1 9 / 31 ... Lista vazia / p Um inteiro seguido de uma lista de inteiros.

.a partir de cada nó.Lista: uma estrutura recursiva: Ex: definição de uma lista de inteiros: . Assim. pode-se ter • Lista vazia. Lista vazia / p Um inteiro seguido de uma lista de inteiros.. • Um inteiro seguido de uma de inteiros... pode-se percorrer a lista lista toda. acesso ao seguinte. p 4 7 1 9 / 32 .

deveria apontar o primeiro elemento. guarda o valor nil ( lista / ).Lista: uma estrutura recursiva: Ex: definição de uma lista de inteiros: Quando a lista estiver vazia o ponteiro que • Lista vazia. de • Um inteiro seguido de uma inteiros... p 4 7 1 9 / 33 . Lista vazia / p Um inteiro seguido de uma lista de inteiros.

{ ou real. tNo = record Dado:tDado. 34 .} tPtNo = ^tNo. Prox :tPtNo.q: tPtNo. var p. etc. end.Definição (recursiva) de um nó: type tDado = integer. char.

{ ou real. 35 .q: tPtNo. etc.Definição (recursiva) de um nó: type tDado = integer. Prox :tPtNo.} tPtNo = ^tNo. var p. end. tNo = record Dado:tDado. char.

type tDado = integer. char. 36 . end.. uma definição semelhante seria. as regras de Pascal exigem a definição na forma anteriormente exposta. etc.. Prox :^tNo.} tNo = record Dado:tDado.q: tPtNo. Contudo.Semanticamente. var p. { ou real.

q: tPtNo. 37 . ser empregados tDado = integer. var p. Definição (recursiva) de um nó: OBS: no início da execução do programa só há ponteiros (p.q) para nós. Estes poderão. tNo = record Dado:tDado. etc. Prox :tPtNo.} para se construir uma lista. end.type dinamicamente. tPtNo = ^tNo. { ou real. char.

p^. acesso ao acesso ao new(q).Exemplo de uso: criação de uma lista com dois elementos: var p. q^.Dado 38 . : p^.Dado := 3. objeto apontado campo q^.Dado := 7.q: tPtNo.Prox := nil. por p específico p^.Prox := q. begin new(p).

q: tPtNo. : p^. acesso ao acesso ao new(q).Exemplo de uso: criação de uma lista com dois elementos: var p.Prox 39 . q^. objeto apontado campo q^. por p específico p^. begin new(p). p^.Prox := nil.Dado := 3.Dado := 7.Prox := q.

q^. : p q 40 .q: tPtNo.Dado := 3. q^.Prox := q. new(q).Prox := nil. p^. begin → new(p).Dado := 7.Alocação de memória var p. p^.

: p q 41 .q: tPtNo. q^. → p^.Dado := 3.Prox := q.Prox := nil.Dado := 7. new(q). p^. q^.Alocação de memória var p. begin new(p).

: p q 7 42 . q^.Prox := q.Alocação de memória var p. begin new(p).Dado := 3. p^.q: tPtNo.Prox := nil. → new(q).Dado := 7. q^. p^.

→ q^.Alocação de memória var p. q^.Dado := 7.q: tPtNo.Prox := q.Prox := nil. begin new(p). : p q 7 43 . p^. new(q). p^.Dado := 3.

new(q). begin new(p). : p q 7 3 44 .Prox := q.Dado := 3.Dado := 7. → p^.q: tPtNo. q^. p^. q^.Prox := nil.Alocação de memória var p.

Alocação de memória var p. begin new(p). → q^. : p q 7 3 45 . q^.q: tPtNo. p^. p^.Prox := q. new(q).Dado := 3.Dado := 7.Prox := nil.

q^. new(q).Dado := 3.Prox := q. p^. → : p q 7 3 / 46 . begin new(p).q: tPtNo. p^. q^.Alocação de memória var p.Prox := nil.Dado := 7.

q := nil. inserir um novo nó entre os dois existentes e armazenar nele o valor 2. p^. : p q 7 3 / 47 .Exemplo 2: dada a lista abaixo.Prox := p^.Dado := 2. : new(q). q^.Prox.Prox := q. q^.

p^.Prox := q.Dado := 2. q := nil. : p q 7 3 / 48 . q^.Prox := p^.Prox. q^.Alocação de memória → : new(q).

Prox := p^. q^. q := nil.Dado := 2.Alocação de memória → : new(q). p^.Prox. : p q 7 3 / 49 .Prox := q. q^.

q := nil. p^.Prox. q^. : p q 2 7 3 / 50 .Prox := p^.Alocação de memória → : new(q).Prox := q.Dado := 2. q^.

Prox := q.Alocação de memória → : new(q). q^.Prox.Dado := 2.Prox := p^. : p q 2 7 3 / 51 . q := nil. p^. q^.

: p q 2 7 3 / 52 . q^.Prox := q. q := nil.Prox.Prox := p^.Alocação de memória → : new(q). p^. q^.Dado := 2.

Prox := p^. q^. q^. q := nil. : p q / 2 7 3 / 53 .Prox. p^.Alocação de memória → : new(q).Dado := 2.Prox := q.

q^.Alocação de memória OBS: por conveniência. : Entretanto.Prox..Prox := q. podem ser bastante dispersas. : 7 p q / → 2 3 / 54 . q^. representamos esquematicamente os nós lado a lado. as suas localização no heap new(q).Dado := 2. p^. q := nil..Prox := p^.

... 55 .Representação esquemática “ideal” p q . disposição física . .. 7 2 3 / 3 / p q 7 2 h e a p Uma possível .

com “new”? 56 .Dúvidas freqüentes: 1) sempre que precisar de um ponteiro. preciso criá-lo.

local ou parâmetro) faz com que o sistema aloque memória para ele. com “new”? Não.Dúvidas freqüentes: 1) sempre que precisar de um ponteiro. preciso criá-lo. >> o simples fato de se declarar o ponteiro (variável global. 57 .

58 . local ou parâmetro) faz com que o sistema aloque memória para ele. preciso criá-lo. >> o simples fato de se declarar o ponteiro (variável global. >> new() deve ser usado para criar um objeto (sem identificação) para o qual o ponteiro usado como argumento apontará.Dúvidas freqüentes: 1) sempre que precisar de um ponteiro. com “new”? Não.

>> new() deve ser usado para criar um objeto (sem identificação) para o qual o ponteiro usado como argumento apontará.Dúvidas freqüentes: 1) sempre que precisar de um ponteiro. 59 . >> o tipo do objeto criado dependerá do tipo de ponteiro. >> o simples fato de se declarar o ponteiro (variável global. preciso criá-lo. local ou parâmetro) faz com que o sistema aloque memória para ele. com “new”? Não.

Dúvidas freqüentes: Caso seja executado o código abaixo.  {apontar para o primeiro elemento             da lista} p q 7 3 / 60 . p. ex. new(q). q := p...

.Dúvidas freqüentes: Caso seja executado o código abaixo..  {apontar para o primeiro elemento             da lista} a) criou-se um elemento. p. p q 7 3 / 61 . new(q). ex. fazendo-se q apontar para ele. q := p.

.. 7 3 / 62 . fazendo-se q apontar para ele. new(q). q := p.Dúvidas freqüentes: Caso seja executado o código abaixo... p. p q b) perdeu-se esse elemento.  {apontar para o primeiro elemento             da lista} a) criou-se um elemento. ex.

devo desalocar os ponteiros. empregando ”dispose”? 63 .Dúvidas freqüentes: 2) ao encerrar um módulo.

>> no encerramento do módulo. todas as variáveis locais e parâmetros (inclusive ponteiros) são desalocados automaticamente. 64 .Dúvidas freqüentes: 2) ao encerrar um módulo. empregando ”dispose”? Não. devo desalocar os ponteiros.

>> ao se utilizar dispose(r). 65 . >> no encerramento do módulo.Dúvidas freqüentes: 2) ao encerrar um módulo. é o objeto referenciado por r que será excluído. devo desalocar os ponteiros. empregando ”dispose”? Não. todas as variáveis locais e parâmetros (inclusive ponteiros) são desalocados automaticamente. Não o ponteiro em si.

Dúvidas freqüentes: 3) quando se cria um objeto (comando new) empregando-se um ponteiro. só se pode empregar aquele ponteiro para desalocar aquele objeto? 66 .

>> o nó não “pertence” ao ponteiro que foi empregado na sua criação.Dúvidas freqüentes: 3) quando se cria um objeto (comando new) empregando-se um ponteiro. 67 . só se pode empregar aquele ponteiro para desalocar aquele objeto? Não.

>> o nó não “pertence” ao ponteiro que foi empregado na sua criação. só se pode empregar aquele ponteiro para desalocar aquele objeto? Não.Dúvidas freqüentes: 3) quando se cria um objeto (comando new) empregando-se um ponteiro. 68 . >> qualquer ponteiro que esteja apontando para certo objeto pode ser usado para a sua desalocação.

Dúvidas freqüentes: 4) ao empregar-se uma variável local (ponteiro) para alocar um objeto. desaparecendo portanto após a execução daquele módulo? 69 . esse objeto será também local.

70 .Dúvidas freqüentes: 4) ao empregar-se uma variável local (ponteiro) para alocar um objeto. >> o objeto criado é alocado na área de memória denominada heap (área própria para alocação dinâmica). esse objeto será também local. desaparecendo portanto após a execução daquele módulo? Não.

71 . desaparecendo portanto após a execução daquele módulo? Não. esse objeto será também local.Dúvidas freqüentes: 4) ao empregar-se uma variável local (ponteiro) para alocar um objeto. >> o objeto criado é alocado na área de memória denominada heap (área própria para alocação dinâmica). >> variáveis de heap não são nem globais nem locais.

Dúvidas freqüentes: Atente bem: Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa. 72 .

73 . Variáveis locais: seu tempo de vida é o intervalo de execução do módulo onde foram declaradas.Dúvidas freqüentes: Atente bem: Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa.

Variáveis de heap: seu tempo de vida é arbitrário.Dúvidas freqüentes: Atente bem: Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa. 74 . Variáveis locais: seu tempo de vida é o intervalo de execução do módulo onde foram declaradas. dependendo de uma criação (new) e da posterior desalocação.

Manuseio de listas encadeadas Para tratar de forma genérica todas as possíveis manipulações de uma lista encadeada. é definido um conjunto de rotinas. Exemplos: • inserir/excluir um elemento no início • inserir /excluir um elemento no final • inserir /excluir um elemento na enésima posição • calcular a soma dos elementos 75 .

/ 76 .Exemplo: inserir elemento V no final Duas situações a se considerar: Lista vazia Lista não vazia / p p ...

. 77 .. ....Para lista vazia: Alocação de memória V 5 p : → .. .

. ..... criar novo nó 78 .? ..Para lista vazia: Alocação de memória V 5 p : → .

. 79 .Para lista vazia: Alocação de memória V 5 p : → new(p).... . .

Para lista vazia:

Alocação de memória V 5 p

: new(p); → ... ...

80

Para lista vazia:

Alocação de memória V 5 p

: new(p); → ...? ...

guardar o valor de V

81

Para lista vazia:

Alocação de memória V 5 p

: new(p); → p^.Dado:=V; ...

82

.Dado:=V. p^.. 5 83 . → .Para lista vazia: Alocação de memória V 5 p : new(p).

? caracterizar último nó 5 84 . → .. p^..Dado:=V.Para lista vazia: Alocação de memória V 5 p : new(p).

→ p^.Para lista vazia: Alocação de memória V 5 p : new(p).Dado:=V. p^.Prox:=nil. 5 85 .

Dado:=V. → 5 / 86 .Para lista vazia: Alocação de memória V 5 p : new(p). p^. p^.Prox:=nil.

Para lista não vazia: p 4 7 1 / 87 .

. 88 .Para lista não vazia: p q 1 / 4 7 Condição facilitadora: fazer com que um ponteiro auxiliar aponte para o último nó..

Alocação de memória V 5 p q : → q:= p. ... . ..Prox.. r 7 2 3 / 89 ... ... while q^.Prox <> nil do q:=q^.

.Prox <> nil do q:=q^. ..Alocação de memória V 5 p q : q:= p.Prox.. r 7 2 3 / 90 . → while q^.. ... ....

.. . .Prox. while q^. r 7 2 3 / 91 ..Alocação de memória V 5 p q : q:= p....... .Prox <> nil do → q:=q^.

r 7 2 3 / 92 .. .... .Prox <> nil do q:=q^. . .Alocação de memória V 5 p q : q:= p....Prox. → while q^..

while q^.. ... .Alocação de memória V 5 p q : q:= p.. ... .. r 7 2 3 / 93 ..Prox.Prox <> nil do → q:=q^.

..Prox <> nil do q:=q^. ..Alocação de memória V 5 p q : q:= p.. ....Prox. r 7 2 3 / 94 .. . → while q^. .

Alocação de memória V 5 p q : q:= p. criar novo nó ..Prox.. while q^..... r 7 2 3 / 95 . . → .? ...Prox <> nil do q:=q^.

.Alocação de memória V 5 p q : q:= p.Prox.. .Prox <> nil do q:=q^.. ... r 7 2 3 / 96 .. while q^. → new(r)..

. .Prox <> nil do q:=q^..Prox..Alocação de memória V 5 p q : q:= p. new(r). . → . while q^. r 7 2 3 / 97 ....

Alocação de memória V 5 p q

:
q:= p; while q^.Prox <> nil do q:=q^.Prox; new(r); → ...? ... guardar o ... valor de V

r

7

2

3 /

98

Alocação de memória V 5 p q

:
q:= p; while q^.Prox <> nil do q:=q^.Prox; new(r); → r^.Dado:=V; ... ...

r

7

2

3 /

99

Alocação de memória V 5 p q

:
q:= p; while q^.Prox <> nil do q:=q^.Prox; new(r); r^.Dado:=V; → ... ...

r

7

2

3 /

5

100

while q^. new(r).. r caracterizar último nó 7 2 3 / 5 101 ..? .Alocação de memória V 5 p q : q:= p.. r^.Prox <> nil do q:=q^.Dado:=V. → ..Prox.

Prox.Prox <> nil do q:=q^. → r^Prox:=nil. r^. .Dado:=V.Alocação de memória V 5 p q : q:= p. while q^.. r 7 2 3 / 5 102 .. new(r).

Prox. new(r)..Prox <> nil do q:=q^.Prox:=nil. while q^. r^..Alocação de memória V 5 p q : q:= p. r^. r 7 2 3 / 5 / 103 .Dado:=V. → .

Prox <> nil do q:=q^..? r ligar nós 7 2 3 / 5 / 104 . new(r). r^.Dado:=V. while q^.. r^. → .Alocação de memória V 5 p q : q:= p.Prox:=nil.Prox.

r^. new(r).Prox <> nil do q:=q^. r^.Prox:=r.Prox:=nil.Alocação de memória V 5 p q : q:= p. r 7 2 3 / 5 / 105 .Prox. → q^.Dado:=V. while q^.

q^.Prox:=nil. → r 7 2 3 5 / 106 . r^.Prox.Alocação de memória V 5 p q : q:= p.Dado:=V. r^. new(r).Prox:=r. while q^.Prox <> nil do q:=q^.

Prox <> nil do q:=q^. q^. p^. {lista não vazia} while q^.. r^..Prox:=nil. new(r). 107 .Prox:=nil.Juntando as duas situações.Prox. {lista vazia} new(p). r^.Prox:=r.Dado:=V. p^.Dado:=V.

r^..Prox:=nil.. 108 . p^. new(r). observe as semelhanças.Dado:=V. r^..Dado:=V.Prox:=r. {lista não vazia} while q^.Prox <> nil do q:=q^..Prox:=nil. {lista vazia} new(p). q^.Prox.Juntando as duas situações. p^.

p^.. q^. 109 .Dado:=V.Prox <> nil do q:=q^.Prox.Dado:=V. observe as semelhanças. p^.Prox:=r. {lista vazia} new(p).. new(r).Juntando as duas situações. {lista não vazia} while q^.Prox:=nil.Prox:=nil. r^... r^.

. r^. p^. p^. new(r).Prox.Juntando as duas situações.Prox <> nil do q:=q^.Prox:=nil.Prox:=r. 110 .. q^. {lista não vazia} while q^.Prox:=nil.Dado:=V.. observe as semelhanças. r^..Dado:=V. {lista vazia} new(p).

procedure InsereNo(var p: tPtNo..r: tPtNo. var q. begin . ele é passado por referência. 111 ..Juntando as duas situações. end... Como existe a possibilidade de p mudar seu conteúdo. V : tDado).

Prox <> nil do q:=q^. end. q^. V : tDado). var q. begin new(r). r^.Prox. 112 .r: tPtNo.. end.Prox:=r. while q^. procedure InsereNo(var p: tPtNo.Juntando as duas situações.. r^.Prox:=nil.Dado:=V. if p = nil then p:= r else begin q:= p.

não só aos posteriores. os nós são ligados.. mas também aos anteriores. / 113 ....Listas duplamente encadeadas Nas listas duplamente encadeadas. p / .

Portanto... a estrutura do nó deve possuir 2 ponteiros. os nós são ligados.Listas duplamente encadeadas Nas listas duplamente encadeadas.. p / . não só aos posteriores. mas também aos anteriores. / 114 ....

..Listas duplamente encadeadas Nas listas duplamente encadeadas.. os nós são ligados.. mas também aos anteriores. Portanto. a estrutura do nó deve possuir 2 ponteiros. / 115 .. p / não há nó anterior.... não só aos posteriores. .

... os nós são ligados... / 116 . . não há nó anterior... .. p / não há nó posterior. Portanto. não só aos posteriores. mas também aos anteriores..Listas duplamente encadeadas Nas listas duplamente encadeadas. a estrutura do nó deve possuir 2 ponteiros.

var p. char.q: tPtNo. / 117 . { ou real. p / .. Dir: tPtNo. tNo = record Esq: tPtNo Dado: tDado.Listas duplamente encadeadas Estrutura: tDado = integer. end. etc.} tPtNo = ^tNo..

Listas duplamente encadeadas Operações: Partindo-se das operações com listas de encadeamento simples. / 118 . p / . basta fazer alguns ajustes..... é necessário considerar que há dois ponteiros.

Considere a rotina de inserção no final para encadeamento simples:
procedure InsereNoFinal(var p:tPtNo; V: tDado); var q,r: tPtNo; begin new(r); r^.Dado:=V; r^.Prox:=nil; if p = nil then p:= r else begin q:= p; while q^.Prox <> nil do q:=q^.Prox; q^.Prox:=r; end; end;

119

...ajustes necessários:
procedure InsereNoFinal(var p:tPtNo; V: tDado); var q,r: tPtNo; begin new(r); r^.Dado:=V; r^.Dir:=nil; if p = nil then begin p:= r; r^.Esq:= nil; end; else begin q:= p; while q^.Dir <> nil do q:=q^.Dir; q^.Dir:=r; r^.Esq := q; end; end;

120

Exercícios (encadeamento simples e duplo): Construir módulos que façam as seguintes operações:
1- Inserir no início da lista; 2- Excluir o primeiro elemento; 3- Excluir o último elemento; 4- Inserir na enésima posição; 5- Excluir o enésimo nó; 6- Fornecer o tamanho da lista 7- Fornecer a soma dos elementos da lista.
121

. pois os ponteiros são dinâmicos.Orientações... a) faça um esquema visual do problema! -> use lápis e borracha.. 122 .Sempre pla neje antes de codi fi car . 1.

.Sempre pla neje antes de codi fi car . a) faça um esquema visual do problema! -> use lápis e borracha.Orientações. b) atenção especial à list a de parâme tros : quais são os parâmetros necessários. pois os ponteiros são dinâmicos. mecanismo de passagem (valor ou referência).... 1. seus tipos. 123 .

q 4 7 3 8 1 / 124 . c) procure identificar co ndiçõe s fa ci li tadoras para a solução de um problema. p . Por exemplo. para excluir o enésimo nó. será necessário um ponteiro auxiliar apontando para ele.....Orientações.

q 4 7 3 8 1 / 125 . Por exemplo.. . para excluir o enésimo nó... c) procure identificar co ndiçõe s fa ci li tadoras para a solução de um problema... p .Orientações..mas isso será necessário um ponteiro auxiliar será suficiente?? apontando para ele.

. Não.... será necessário encadear o anterior com o sucessor.Orientações. do nó que guarda o valor 8. ex. No processo de exclusão. p .. q 4 7 3 8 1 / 126 . p...

..Orientações. r q 4 7 3 8 1 / 127 ... Portanto a condição facilitadora pede também um ponteiro para o nó anterior.. p ..

. Agora ficou simples... Portanto a condição facilitadora pede também um ponteiro para o nó anterior. p ... r q 4 7 3 8 1 / 128 ..Orientações...

..... 129 ..Orientações.a identificação da condição facilitadora permite a divisão do problema em duas etapas. reduzindo-se a complexidade. .

Primeiramente. 2 . procure a solução para o caso mais geral. Depois considere as situações especiais..Orientações.... 130 .

procure a solução para o caso mais geral..Orientações. inserir o tratamento especial..Primeiramente. Depois considere as situações especiais. Ex: Inserir na enésima posição: raciocinar para lista não vazia e inserção no meio da lista. 2 . . 131 . Depois considerar...e se a lista estiver vazia? .e se a posição for a primeira (ou a última)? Quando a solução geral não funcionar para esses casos...