ponteiros em pascal - ufsprog2.files.wordpress.com › 2009 › 08 › 01-ponteirospascal.pdf1...
TRANSCRIPT
-
1
Ponteiros em Pascal Variáveis ponteiros são aquelas que guardam o endereço de outra, possibi-litando 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}
-
2
Operador @ Operador unário que retorna o endereço de uma variávelprogram 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.
-
3
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.
Alocação de memória
→
A B
PtA
S
PtB
PtS
-
4
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.
Alocação de memória
→
A 2 B
PtA
S
PtB
PtS
-
5
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.
Alocação de memória
→
A 2 B 3
PtA
S
PtB
PtS
-
6
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.
Alocação de memória
→
A 2 B 3
PtA
S
PtB
PtS
-
7
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.
Alocação de memória
→
A 2 B 3
PtA
S
PtB
PtS
-
8
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.
Alocação de memória
→
A 2 B 3
PtA
S
PtB
PtS
-
9
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.
Alocação de memória
→
A 2 B 3
PtA
S 5
PtB
PtS
-
10
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.
Alocação de memória
A 2 B 3
PtA
S 5
PtB
PtS
5
-
11
procedure New( ) Cria dinamicamente (em tempo de execução) uma nova variável e faz uma variável ponteiro apontar para ela.type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
-
12
type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
Alocação de memória
→ P
-
13
type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
Alocação de memória
→P
-
14
type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
Alocação de memória
→
P
Bom Dia!
-
15
type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
Alocação de memória
→
P
Bom Dia!
Bom Dia!
-
16
type Str18 = string[18];var P: ^Str18;begin New(P); P^ := 'Bom dia!'; Writeln (P^) Dispose(P); end.
Alocação de memória
P
OBS: a procedure Dispose libera uma variável criada dinamicamente, para que o SO possa reutilizar
o espaço de memória correspondente.
-
17
Um ponteiro recebendo o valor de um outro...
Um ponteiro recebe o valor de um outro através do comando de atribuição... Ex: q:= p;
Quando isso acontece, ele passa a apontar para o mesmo objeto que o outro aponta
-
18
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
-
19
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
-
20
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→ p
q
r
5
-
21
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→ p
q
r
5
-
22
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
5
-
23
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
5
-
24
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
5
5
-
25
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
-
26
var p,q,r: ^integer; begin new(p); p^ := 5; new(q); q:= p; r := p; {ou q} writeln(p^);{ou q^ ou r^ } dispose(q);{ou p ou r } :
Alocação de memória
→
p
q
r
ATENÇÃO: observe que a partir de q:=p;, perdeu-se o acesso à variável criada com
new(q)...Portanto, o manuseio de ponteiros
exige cuidado!
-
27
Listas linearesEm várias situações em programação temos que lidar com listas de elementos cujo tamanho exato é desconhecido. Estratégias:
• Empregar um agregado homogêneo (array) superdimensionado.
1 2 3...
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
/
-
28
Quando adotar uma ou outra solução?
• Agregado homogêneo: quando pudermos determinar com segurança o tamanho máximo.
• Listas encadeada: - quando for difícil estimar o tamanho máximo com segurança; e/ou...- quando se desejar maior agilidade nas inclusões ou exclusões de novos elementos.
-
29
Lista: uma estrutura recursiva:Ex: definição de uma lista de inteiros:• Lista vazia;• Um inteiro seguido de uma lista de
inteiros.
p
/4 7 1 9
/ p
Lista vazia Um inteiro seguido de umalista de inteiros...
-
30
Lista: uma estrutura recursiva:Ex: definição de uma lista de inteiros:• Lista vazia;• Um inteiro seguido de uma lista de
inteiros.
p
/4 7 1 9
/ p
Lista vazia
O ponteiro contido noprimeiro nó aponta para a lista formada
pelos demais nós
Um inteiro seguido de umalista de inteiros...
-
31
Lista: uma estrutura recursiva:Ex: definição de uma lista de inteiros:• Lista vazia;• Um inteiro seguido de uma lista de
inteiros.
p
/4 7 1 9
/ p
Lista vazia
OBS: para se ter acesso aos elementos da lista é necessário que haja sempre uma variável apontando para a “cabeça” da
lista...
Um inteiro seguido de umalista de inteiros...
-
32
Lista: uma estrutura recursiva:Ex: definição de uma lista de inteiros:• Lista vazia;• Um inteiro seguido de uma lista de
inteiros.
p
/4 7 1 9
/ p
Lista vazia
...a partir de cada nó, pode-se ter acesso ao seguinte.
Assim, pode-se percorrer a lista toda.
Um inteiro seguido de umalista de inteiros...
-
33
Lista: uma estrutura recursiva:Ex: definição de uma lista de inteiros:• Lista vazia;• Um inteiro seguido de uma lista de
inteiros.
p
/4 7 1 9
/ p
Lista vazia
Quando a lista estiver vazia o ponteiro que deveria apontar o primeiro elemento,
guarda o valor nil ( / ).
Um inteiro seguido de umalista de inteiros...
-
34
Definição (recursiva) de um nó:type tDado = integer; { ou real, char, etc.} tPtNo = ^tNo; tNo = record Dado:tDado; Prox :tPtNo; end;var p,q: tPtNo;
-
35
Definição (recursiva) de um nó:type tDado = integer; { ou real, char, etc.} tPtNo = ^tNo; tNo = record Dado:tDado; Prox :tPtNo; end;var p,q: tPtNo;
-
36
Semanticamente, uma definição semelhante seria...
type tDado = integer; { ou real, char, etc.} tNo = record Dado:tDado; Prox :^tNo; end;var p,q: tPtNo;
Contudo, as regras de Pascal exigem a definição na forma anteriormente exposta.
-
37
Definição (recursiva) de um nó:type tDado = integer; { ou real, char, etc.} tPtNo = ^tNo; tNo = record Dado:tDado; Prox :tPtNo; end;var p,q: tPtNo;
OBS: no início da execução do programa só há ponteiros (p,q) para nós. Estes poderão,
dinamicamente, ser empregados para se construir uma lista.
-
38
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Exemplo de uso: criação de uma lista com dois elementos:
p^.Dadoacesso ao
objeto apontado por p
acesso ao campo
específico
-
39
p^.Proxacesso ao
objeto apontado por p
acesso ao campo
específico
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Exemplo de uso: criação de uma lista com dois elementos:
-
40
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
-
41
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
-
42
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→ p
q
7
-
43
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
7
-
44
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
7 3
-
45
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
7 3
-
46
var p,q: tPtNo;begin new(p); p^.Dado := 7; new(q); q^.Dado := 3; p^.Prox := q; q^.Prox := nil;
:
Alocação de memória
→
p
q
7 3 /
-
47
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Exemplo 2: dada a lista abaixo, inserir um novo nó entre os dois existentes e armazenar nele o valor 2.
p
7 3 /
q
-
48
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q
-
49
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q
-
50
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q
2
-
51
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q
2
-
52
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q
2
-
53
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q /
2
-
54
: new(q); q^.Dado := 2; q^.Prox := p^.Prox; p^.Prox := q; q := nil; :
Alocação de memória
→
p
7 3 /
q /
2
OBS: por conveniência, representamos esquematicamente os nós lado a lado.
Entretanto, as suas localização no heappodem ser bastante dispersas...
-
55
Representação esquemática “ideal”
p
7 3 /
q
2
pq
7
2
3/
heap
.
.
....
...
Uma possível disposição física
-
56
Dúvidas freqüentes:1) sempre que precisar de um ponteiro, preciso
criá-lo, com “new”?
-
57
Dúvidas freqüentes:1) sempre que precisar de um ponteiro, preciso
criá-lo, com “new”?Não.
>> o simples fato de se declarar o ponteiro (variável global, local ou parâmetro) faz com que o sistema aloque memória para ele.
-
58
Dúvidas freqüentes:1) sempre que precisar de um ponteiro, preciso
criá-lo, com “new”?Não.
>> o simples fato de se declarar o ponteiro (variável global, local ou parâmetro) faz com que o sistema aloque memória para ele.
>> new() deve ser usado para criar um objeto (sem identificação) para o qual o ponteiro usado como argumento apontará.
-
59
Dúvidas freqüentes:1) sempre que precisar de um ponteiro, preciso
criá-lo, com “new”?Não.
>> o simples fato de se declarar o ponteiro (variável global, local ou parâmetro) faz com que o sistema aloque memória para ele.
>> new() deve ser usado para criar um objeto (sem identificação) para o qual o ponteiro usado como argumento apontará.
>> o tipo do objeto criado dependerá do tipo de ponteiro.
-
60
Dúvidas freqüentes:Caso seja executado o código abaixo, p. ex...
new(q);q := p; {apontar para o primeiro elemento da lista}
p
7 3 /
q
-
61
Dúvidas freqüentes:
p
7 3 /
q
Caso seja executado o código abaixo, p. ex...new(q);q := p; {apontar para o primeiro elemento da lista}
a) criou-se um elemento, fazendo-se q apontar para ele.
-
62
Dúvidas freqüentes:Caso seja executado o código abaixo, p. ex...
new(q);q := p; {apontar para o primeiro elemento da lista}
a) criou-se um elemento, fazendo-se q apontar para ele.b) perdeu-se esse elemento...
p
7 3 /
q
-
63
Dúvidas freqüentes:2) ao encerrar um módulo, devo desalocar os
ponteiros, empregando ”dispose”?
-
64
Dúvidas freqüentes:2) ao encerrar um módulo, devo desalocar os
ponteiros, empregando ”dispose”?Não.
>> no encerramento do módulo, todas as variáveis locais e parâmetros (inclusive ponteiros) são desalocados automatica-mente.
-
65
Dúvidas freqüentes:2) ao encerrar um módulo, devo desalocar os
ponteiros, empregando ”dispose”?Não.
>> no encerramento do módulo, todas as variáveis locais e parâmetros (inclusive ponteiros) são desalocados automatica-mente.>> ao se utilizar dispose(r), é o objeto referenciado por r que será excluído. Não o ponteiro em si.
-
66
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?
-
67
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?
Não. >> o nó não “pertence” ao ponteiro que foi empregado na sua criação.
-
68
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?
Não. >> o nó não “pertence” ao ponteiro que foi empregado na sua criação.>> qualquer ponteiro que esteja apontando para certo objeto pode ser usado para a sua desalocação.
-
69
Dúvidas freqüentes:4) ao empregar-se uma variável local
(ponteiro) para alocar um objeto, esse objeto será também local, desaparecendo portanto após a execução daquele módulo?
-
70
Dúvidas freqüentes:4) ao empregar-se uma variável local
(ponteiro) para alocar um objeto, esse objeto será também local, desaparecendo portanto após a execução daquele módulo?
Não. >> o objeto criado é alocado na área de memória denominada heap (área própria para alocação dinâmica).
-
71
Dúvidas freqüentes:4) ao empregar-se uma variável local
(ponteiro) para alocar um objeto, esse objeto será também local, desaparecendo portanto após a execução daquele módulo?
Não. >> 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.
-
72
Dúvidas freqüentes:Atente bem:
Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa.
-
73
Dúvidas freqüentes:Atente bem:
Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa.Variáveis locais: seu tempo de vida é o intervalo de execução do módulo onde foram declaradas.
-
74
Dúvidas freqüentes:Atente bem:
Variáveis globais: seu tempo de vida é o intervalo de tempo de execução do programa.Variáveis locais: seu tempo de vida é o intervalo de execução do módulo onde foram declaradas.Variáveis de heap: seu tempo de vida é arbitrário, dependendo de uma criação (new) e da posterior desalocação.
-
75
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
-
76
Exemplo: inserir elemento V no finalDuas situações a se considerar:Lista vazia Lista não vazia
p
/
/ p
...
-
77
: ... ... ...
Alocação de memória
→
p
V5
Para lista vazia:
-
78
: ...? ... ...
Alocação de memória
→
p
V5
Para lista vazia:
criar novo nó
-
79
: new(p); ... ...
Alocação de memória
→
p
V5
Para lista vazia:
-
80
: new(p); ... ...
Alocação de memória
→
p
V5
Para lista vazia:
-
81
: new(p); ...? ...
Alocação de memória
→
p
V5
Para lista vazia:
guardar ovalor de V
-
82
: new(p); p^.Dado:=V; ...
Alocação de memória
→
p
V5
Para lista vazia:
-
83
: new(p); p^.Dado:=V; ...
Alocação de memória
→
p
V5
5
Para lista vazia:
-
84
: new(p); p^.Dado:=V; ...?
Alocação de memória
→
p
V5
5
Para lista vazia:
caracterizarúltimo nó
-
85
: new(p); p^.Dado:=V; p^.Prox:=nil;
Alocação de memória
→
p
V5
5
Para lista vazia:
-
86
: new(p); p^.Dado:=V; p^.Prox:=nil;
Alocação de memória
→
p
V5
5 /
Para lista vazia:
-
87
p
4 7 1 /
Para lista não vazia:
-
88
Para lista não vazia:
p
4 7 1 /
Condição facilitadora:fazer com que um ponteiro auxiliar aponte para o último nó...
q
-
89
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
90
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
91
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
92
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
93
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
94
: q:= p; while q^.Prox nil do q:=q^.Prox; ... ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
95
: q:= p; while q^.Prox nil do q:=q^.Prox; ...? ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
criar novo nó
-
96
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
97
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); ... ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
98
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); ...? ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
guardar ovalor de V
-
99
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
-
100
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; ... ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
5
-
101
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; ...? ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
5
caracterizarúltimo nó
-
102
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; r^Prox:=nil; ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
5
-
103
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; r^.Prox:=nil; ...
Alocação de memória
→
p
7 3 /
q
2
r
V5
5 /
-
104
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; r^.Prox:=nil; ...?
Alocação de memória
→
p
7 3 /
q
2
r
V5
5 /ligar nós
-
105
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; r^.Prox:=nil; q^.Prox:=r;
Alocação de memória
→
p
7 3 /
q
2
r
V5
5 /
-
106
: q:= p; while q^.Prox nil do q:=q^.Prox; new(r); r^.Dado:=V; r^.Prox:=nil; q^.Prox:=r;
Alocação de memória
→
p
7 3
q
2
r
V5
5 /
-
107
Juntando as duas situações...{lista vazia}new(p);p^.Dado:=V;p^.Prox:=nil;
{lista não vazia}while q^.Prox nil do q:=q^.Prox; new(r);r^.Dado:=V;r^.Prox:=nil;q^.Prox:=r;
-
108
Juntando as duas situações...{lista vazia}new(p);p^.Dado:=V;p^.Prox:=nil;
{lista não vazia}while q^.Prox nil do q:=q^.Prox; new(r);r^.Dado:=V;r^.Prox:=nil;q^.Prox:=r;
observe as semelhanças...
-
109
Juntando as duas situações...{lista vazia}new(p);p^.Dado:=V;p^.Prox:=nil;
{lista não vazia}while q^.Prox nil do q:=q^.Prox; new(r);r^.Dado:=V;r^.Prox:=nil;q^.Prox:=r;
observe as semelhanças...
-
110
Juntando as duas situações...{lista vazia}new(p);p^.Dado:=V;p^.Prox:=nil;
{lista não vazia}while q^.Prox nil do q:=q^.Prox; new(r);r^.Dado:=V;r^.Prox:=nil;q^.Prox:=r;
observe as semelhanças...
-
111
Juntando as duas situações...procedure InsereNo(var p: tPtNo; V : tDado);var q,r: tPtNo;begin ...
end;
Como existe a possibilidade de p mudar seu conteúdo, ele é passado por referência.
-
112
Juntando as duas situações...procedure InsereNo(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;
-
113
Listas duplamente encadeadas
p
/.../
Nas listas duplamente encadeadas, os nós são ligados, não só aos posteriores, mas também aos anteriores...
-
114
Listas duplamente encadeadas
p
/.../
Nas listas duplamente encadeadas, os nós são ligados, não só aos posteriores, mas também aos anteriores...
Portanto, a estrutura do nó deve possuir 2 ponteiros...
-
115
Listas duplamente encadeadas
p
/.../não há nóanterior...
Nas listas duplamente encadeadas, os nós são ligados, não só aos posteriores, mas também aos anteriores...
Portanto, a estrutura do nó deve possuir 2 ponteiros...
-
116
Listas duplamente encadeadas
p
/.../não há nóanterior...
não há nóposterior..
.
Nas listas duplamente encadeadas, os nós são ligados, não só aos posteriores, mas também aos anteriores...
Portanto, a estrutura do nó deve possuir 2 ponteiros...
-
117
Listas duplamente encadeadasEstrutura:tDado = integer; { ou real, char, etc.}tPtNo = ^tNo;tNo = record Esq: tPtNo Dado: tDado; Dir: tPtNo; end;var p,q: tPtNo;
p
/.../
-
118
Listas duplamente encadeadasOperações:
Partindo-se das operações com listas de
encadeamento simples, basta fazer alguns
ajustes.
p
/.../
é necessário considerar que
há dois ponteiros...
-
119
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;
-
120
...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;
-
121
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.
-
122
Orientações...
1- Sempre pla neje antes de codi fi car .
a) faça um esquema visual do problema!
-> use lápis e borracha, pois os
ponteiros são dinâmicos...
-
123
Orientações...
1- Sempre pla neje antes de codi fi car .
a) faça um esquema visual do problema!
-> use lápis e borracha, pois os
ponteiros são dinâmicos...
b) atenção especial à list a de parâme tros :
quais são os parâmetros necessários, seus
tipos, mecanismo de passagem (valor ou
referência);
-
124
Orientações...
c) procure identificar co ndiçõe s
fa ci li tadoras para a solução de um
problema.
Por exemplo, para excluir o enésimo nó,
será necessário um ponteiro auxiliar
apontando para ele.
p
4 7
q
1 /3 8...
-
125
Orientações...
c) procure identificar co ndiçõe s
fa ci li tadoras para a solução de um
problema.
Por exemplo, para excluir o enésimo nó,
será necessário um ponteiro auxiliar
apontando para ele.
p
4 7
q
1 /3 8...
...mas isso será
suficiente??
-
126
Orientações...
Não. No processo de exclusão, p. ex., do nó que
guarda o valor 8, será necessário encadear o
anterior com o sucessor...
p
4 7
q
1 /3 8...
-
127
Orientações...
Portanto a condição facilitadora pede também
um ponteiro para o nó anterior...
p
4 7
q
1 /3 8...
r
-
128
Orientações...
Portanto a condição facilitadora pede também
um ponteiro para o nó anterior...
p
4 7
q
1 /3 8...
r
Agora ficou simples...
-
129
Orientações...
...a identificação da condição facilitadora
permite a divisão do problema em duas
etapas, reduzindo-se a complexidade...
-
130
Orientações...2 - Primeiramente, procure a solução para o
caso mais geral. Depois considere as situações especiais...
-
131
Orientações...2 - Primeiramente, procure a solução para o
caso mais geral. 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.
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, inserir o tratamento especial.