ponteiros em pascal - ifc-camboriu.edu.brmarcelo/estrutura de dados/apostila... · 1 ponteiros em...

Post on 09-Feb-2019

224 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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á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.

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 lineares

Em 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 final

Duas situações a se considerar:

Lista vazia Lista não vazia

p

/

/ p

...

77

: ... ... ...

Alocação de memória

p

V

5

Para lista vazia:

78

: ...? ... ...

Alocação de memória

p

V

5

Para lista vazia:

criar novo nó

79

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

Alocação de memória

p

V

5

Para lista vazia:

80

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

Alocação de memória

p

V

5

Para lista vazia:

81

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

Alocação de memória

p

V

5

Para lista vazia:

guardar ovalor de V

82

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

Alocação de memória

p

V

5

Para lista vazia:

83

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

Alocação de memória

p

V

5

5

Para lista vazia:

84

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

Alocação de memória

p

V

5

5

Para lista vazia:

caracterizarúltimo nó

85

: new(p); p^.Dado:=V; p^.Prox:=nil;

Alocação de memória

p

V

5

5

Para lista vazia:

86

: new(p); p^.Dado:=V; p^.Prox:=nil;

Alocação de memória

p

V

5

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

V

5

90

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ... ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

91

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ... ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

92

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ... ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

93

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ... ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

94

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ... ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

95

: q:= p; while q^.Prox <> nil do q:=q^.Prox; ...? ... ... ...

Alocação de memória

p

7 3 /

q

2

r

V

5

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

V

5

97

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

Alocação de memória

p

7 3 /

q

2

r

V

5

98

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

Alocação de memória

p

7 3 /

q

2

r

V

5

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

V

5

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

V

5

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

V

5

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

V

5

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

V

5

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

V

5

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

V

5

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

V

5

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 encadeadas

Estrutura: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 encadeadas

Operaçõ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.

top related