Upload
internet
View
109
Download
1
Embed Size (px)
Citation preview
11/04/23 Fábio Lopes Caversan 1
Listas Ligadas – Conceitos Avançados
Estruturas de Dados e Algoritmos
Fábio Lopes Caversan 211/04/23
Listas Circulares Dado um ponteiro p para um nó numa lista linear Não é possível atingir nenhum dos nós que antecedem
o Node p Ao atravessar uma lista, o ponteiro externo deve ser
preservado para não perdemos a lista Numa lista circular o campo Next do último nó, ao
invés de ponteiro nulo, contém um ponteiro para o primeiro nó
Fábio Lopes Caversan 311/04/23
Primeiro nóPrimeiro nó Último nóÚltimo nó
list
Atingi-se qualquer ponto da lista, não importando o ponto de partida
Não existe mais um “primeiro” e “último” nó natural Uma convenção é considerar o último nó como
apontado pelo ponteiro externo (list). E o nó seguinte torna-se o primeiro nó
Último nó: list Primeiro nó: list.Next Permite incluir/remover elemento a partir do início
ou do final de uma lista Por convenção: ponteiro nulo representa uma lista
circular vazia
Fábio Lopes Caversan 411/04/23
Pilha como lista circular
Seja stack um ponteiro para o último nó de uma lista circular
O primeiro nó é o topo da pilha A função Empty pode ser:
Empty (){return (stack == NULL);
}
Fábio Lopes Caversan 511/04/23
Chamando Push(x)public void Push (object x)
{
Node p;
p = new Node ( );
p.Info = x;
if (Empty ())
stack = p;
else
p.Next = stack.Next;
stack.Next = p;
}
Push é mais complexa para lista circulares do que para listas lineares
Fábio Lopes Caversan 611/04/23
Chamando Pop ()
public object Pop (){ object x; Node p; if (Empty ()) throw new Exception (“Underflow da pilha”); p = stack.Next; x = p.Info; if ( p == stack) stack = NULL; /* só havia um nó na pilha */ else stack.Next = p.Next; p = NULL; return x;}
Fábio Lopes Caversan 711/04/23
Agora é vez das filas . . . É mais fácil representar uma fila como
lista circular do que lista linear É usado apenas um único ponteiro p p é o final da fila e nó seguinte é seu início A função Empty() é idêntica à da pilha Remove () é idêntica à pop, basta
substituir stack por queue que é um ponteiro para a fila
Fábio Lopes Caversan 811/04/23
Chamando Insert(x)
Insert (int x){ Node p; p = new Node( ); p.Info = x; if (Empty()) queue = p; else p.Next = queue.Next; queue.Next = p; queue = p; return;}
Insert (x) equivale a:
Push (x);queue = queue.Next;
Isso significa que para inserir um elemento no final de uma fila circular, o elemento é inserido no início da fila e o ponteiro da lista circular avança um elemento para que o novo elemento ocupe o final.
Fábio Lopes Caversan 911/04/23
Operações primitivas para listas circulares
InsertAfter(x) é semelhante à rotina das listas linearespublic object DeleteAfter (Node p){ object x; Node q; if (( p == NULL || (p == p.Next)) throw new Exception(“Não há próximo nó para remover”); q = p.Next; x = q.Info; p.Next = q.Next; q = NULL; return x;}
Fábio Lopes Caversan 1011/04/23
O problema de Josephus Solução com lista circularSolução com lista circular Um grupo de soldados circundado por uma Um grupo de soldados circundado por uma
força inimiga esmagadoraforça inimiga esmagadora Não há esperanças de vitória Não há esperanças de vitória O negócio é escapar . . .O negócio é escapar . . . Mas só existe um cavalo disponível!!!!Mas só existe um cavalo disponível!!!!
Que tal um acordo para escolher o soldado felizardo ?
Fábio Lopes Caversan 1111/04/23
É sorteado um número n de um chapéu e também o É sorteado um número n de um chapéu e também o nome de um soldadonome de um soldado
Iniciando no soldado, eles começam a contar no Iniciando no soldado, eles começam a contar no sentido horáriosentido horário
O soldado no qual a contagem n é finalizado, é retirado O soldado no qual a contagem n é finalizado, é retirado do círculodo círculo
A contagem reinicia no soldado seguinte ao retirado do A contagem reinicia no soldado seguinte ao retirado do círculocírculo
Todo soldado que sair do círculo, não entra mais no Todo soldado que sair do círculo, não entra mais no processoprocesso
O último soldado é o felizardo para escapar com o O último soldado é o felizardo para escapar com o cavalocavalo
Fábio Lopes Caversan 1211/04/23
Listas duplamente ligadas
Uma lista circular tem vantagens sobre uma lista linear
Mas apresenta várias deficiências: não dá para percorrê-la no sentido contrário, nem um nó pode ser ser eliminado, em função de apenas um ponteiro para esse nó
Para sobrepujar a deficiências acima, o mais adequado é utilizar a lista duplamente ligada
Fábio Lopes Caversan 1311/04/23
nulo nulo
Lista linear duplamente ligadaLista linear duplamente ligada
Lista circular duplamente ligada sem cabeçalhoLista circular duplamente ligada sem cabeçalho
Fábio Lopes Caversan 1411/04/23
Observações
Cada nó tem dois ponteiros: um para seu predecessor e outro para seu sucessor
De fato os termos predecessor e sucessor não fazem sentido, porque a listas duplamente ligadas são simétricas
As listas duplamente ligadas podem ser lineares ou circulares e, podem conter ou não nó de cabeçalho
Um nós tem três campos: Info, Prior e Next que contem ponteiros para os nós em ambos os lados
Fábio Lopes Caversan 1511/04/23
Inserindo um novo primeiro elemento numa lista duplamente ligada
novo
Info info
null
Info
null
novonull
Info Info
null
Info
Fábio Lopes Caversan 1611/04/23
Inserindo um novo elemento no meio de uma lista duplamente ligada
novo
Info info
null
Info
null
novo
Info info
null
Info
null
Fábio Lopes Caversan 1711/04/23
Inserindo um novo último elemento numa lista duplamente ligada
novo
Info info
null
Info
null
novo null
Info info
Info
null
Fábio Lopes Caversan 1811/04/23
Apagando o primeiro elemento
Info
null
Info
Info
null
Info
null
Info
null
Excluído
null null
Fábio Lopes Caversan 1911/04/23
Apagando o elemento do meio
Info
null
Info
Info
null
Info
null
Excluído
null null
Info
null
Fábio Lopes Caversan 2011/04/23
Apagando o último elemento
Info
null
Info
Info
null
Excluído
null null
Infp
null
Info
null
Fábio Lopes Caversan 2111/04/23
Representando o nó
public class Node {
object info;
Node prior, next;
... // Gets e Sets
};
Fábio Lopes Caversan 2211/04/23
Eliminação de um nó em listas duplamente ligadas
public object Delete (Node p){ object x; Node q,r; if (p == NULL) throw new Exception(“Renovação vazia”); x = p.Info; q = p.Prior; r = p.Next; q.Next = r; r.Prior = q; p = NULL; return;}
Fábio Lopes Caversan 2311/04/23
Inserindo um nó com informação x à direita de pInsertAfter (Node p, int x){ Node q,r; if (p == NULL) throw new Exception(“Inserção vazia”); q = new Node ( ); q.Info = x; r = p.Next; r.Prior = q; q.Next = r; q.Left = p; p.Next = q; return;}