ponteiros em pascal - ufsprog2.files.wordpress.com › 2009 › 08 › 01-ponteirospascal.pdf1...

131
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}

Upload: others

Post on 08-Feb-2021

5 views

Category:

Documents


0 download

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.