Listas duplamente ligadas - declaração em C
struct Nodo {
INFO Elemento; struct Nodo *Prox; struct Nodo *Ant;
};
typedef struct Nodo *PNodo; PNodo Head, Tail;
Considere-se as seguintes operações sobre a estrutura INFO:
Mostrar no monitor os dados associados e um elemento do tipo INFO
void MostrarElemento (INFO X)
Criar um elemento do tipo INFO
INFO CriarElemento ()
Comparar 2 elementos, X e Y, do tipo INFO
int CompararElementos (INFO X, INFO Y)
Criar uma lista
Esquema:
Entrada: os ponteiros para a cabeça (Head) e para a cauda (Tail) da lista Saída: os mesmos ponteiros a apontarem para NULL (lista vazia)
void Criar (PNodo *Head, PNodo *Tail) {
*Head = NULL; *Tail = NULL;
}
Criar um nodo duma lista
Esquema
Entrada: um elemento X
Saída: um ponteiro para um nodo (informação + link)
PNodo CriarNodo (INFO X) {
PNodo P;
P = (PNodo) malloc(sizeof(struct Nodo)); if (P == NULL) return NULL; PElemento = X; PProx = NULL; PAnt = NULL; return P; }
Libertar/destruir um nodo duma lista
Esquema:
Entrada: um ponteiro para o nodo que se pretende destruir Saída: o ponteiro a apontar para NULL
PNodo LibertarNodo (PNodo P) { free(P);
P = NULL; return P; }
Verificar se uma lista está vazia
Entrada: um ponteiro para a cabeça da lista Saída: 1 (lista vazia) ou 0 (lista não vazia)
int Vazia (PNodo Head) {
if (Head == NULL)
return 1;
else
return 0;
Listar/mostrar os elementos duma lista
Entrada: um ponteiro para a cauda da lista
Saída: nada (apenas mostra os elementos da lista no écran) Listar da cabeça para a cauda (versão iterativa):
void Listar (PNodo Head) {
PNodo P = Head; while (P != NULL) { MostrarElemento(PElemento); P = PProx; } }
Listar da cauda para a cabeça (versão iterativa):
void ListarContrario (PNodo Tail) {
PNodo P = Tail; while (P != NULL) { MostrarElemento(PElemento); P = PAnt; } }
Determinar o tamanho duma lista
Entrada: um ponteiro para a cabeça da lista Saída: o tamanho da lista
int Tamanho (PNodo Head) {
PNodo P = Head; int tam = 0; while (P != NULL) { tam++; P = PProx; } return tam; }
Consultar um elemento numa lista
Entrada: um ponteiro para a cabeça da lista e o elemento a consultar Saída: 1 (existe o elemento na lista) ou 0 (não existe o elemento na lista) Realizar consulta da cabeça para a cauda da lista:
int ConsultarCabeca (PNodo Head, INFO X) {
PNodo P = Head;
if (Head == NULL)
return 0;
while (CompararElementos(PElemento, X) != 0 && PProx != NULL)
P = PProx;
if (CompararElementos(PElemento, X) == 0)
return 1;
return 0; }
Consultar um elemento numa lista
Entrada: um ponteiro para a cabeça da lista e o elemento a consultar Saída: 1 (existe o elemento na lista) ou 0 (não existe o elemento na lista) Realizar consulta da cauda para a cabeça da lista:
int ConsultarCauda (PNodo Tail, INFO X) {
PNodo P = Tail;
if (Tail == NULL)
return 0;
while (CompararElementos(PElemento, X) != 0 && PAnt != NULL)
P = PAnt;
if (CompararElementos(PElemento, X) == 0)
return 1;
return 0; }
Procurar o nodo dum elemento duma lista
Entrada: um ponteiro para a cabeça da lista e o elemento a procurar
Saída: devolve o ponteiro do nodo que contém o elemento a procurar (existe sempre)
PNodo Procurar (PNodo Head, INFO X) {
PNodo P = Head;
while (CompararElementos(PElemento, X) != 0)
P = PProx; return P;
Inserir um elemento numa lista – o primeiro elemento da lista:
Esquema:
Entrada: os ponteiros para a cabeça e para a cauda da lista, e o elemento a inserir Saída: a lista atualizada (com um elemento)
void InserirPrimeiroElemento (PNodo *Head, PNodo *Tail, INFO X) {
PNodo P; P = CriarNodo(X); if (P != NULL){ *Head = P; *Tail = P; } }
Inserir um elemento numa lista - inserir à cabeça da lista (lista não vazia)
Esquema:
Entrada: um ponteiro para a cabeça da lista e o elemento a inserir Saída: a lista atualizada (com mais um elemento)
PNodo InserirCabeca (PNodo Head, INFO X) {
PNodo P; P = CriarNodo(X); if (P == NULL) return Head; PProx = Head; (1) HeadAnt = P; (2) Head = P; (3) return Head; }
Inserir na cauda da lista (lista não vazia)
Esquema:
Entrada: um ponteiro para a cauda da lista e o elemento a inserir Saída: a lista atualizada (com mais um elemento)
PNodo InserirCauda (PNodo Tail, INFO X) {
PNodo P; P = CriarNodo(X); if (P == NULL) return Tail; TailProx = P; (1) PAnt = Tail; (2) Tail = P; (3) return Tail; }
Inserir no meio de uma lista ordenada e não vazia
Inserir no meio de uma lista ordenada e não vazia
Entrada: um ponteiro para a cabeça da lista e o elemento a inserir Saída: a lista atualizada (com mais um elemento)
PNodo InserirMeio (PNodo Head, INFO X) {
PNodo P, PAnt, PProx;
PAnt = ProcurarOrdem(Head, X); P = CriarNodo(X); if (P == NULL) return Head; PProx = PAntProx; PProx = PAntProx; (1) PAnt = PAnt; (2) PAntProxAnt = P; (3) PAntProx = P; (4) return Head; }
Inserir no meio de uma lista ordenada e não vazia
Localizar o nodo que ficará antes do nodo a inserir (lista ordenada):
Entrada: um ponteiro para a cabeça da lista e o elemento a procurar
Saída: devolve o ponteiro do nodo anterior àquele que contém o elemento a procurar (ou NULL
se este nodo estiver à cabeça)
PNodo ProcurarOrdem (PNodo Head, INFO X) {
PNodo P, PAnt;
P = Head; PAnt = NULL;
while (CompararElementos(PElemento, X) <= 0 && PProx != NULL){
PAnt = P; P = PProx; } if (CompararElementos(PElemento, X) <= 0) return P; return PAnt; }
Remover um elemento duma lista (o único elemento da lista)
Esquema:
Entrada: os ponteiros para a cabeça e cauda da lista (com um só elemento) Saída: a lista atualizada (vazia)
void RemoverUnicoElemento (PNodo *Head, PNodo *Tail) {
PNodo P = *Head;
*Head = NULL; (1) *Tail = NULL; (2) P = LibertarNodo(P); (3)
Remover um elemento duma lista (o da cabeça da lista)
Esquema:
Entrada: um ponteiro para a cabeça da lista
Saída: a lista atualizada (com menos um elemento)
PNodo RemoverCabeca (PNodo Head) {
PNodo P = Head; HeadProxAnt = NULL; (1) Head = HeadProx; (2) P = LibertarNodo(P); (3) return Head; }
Remover um elemento duma lista (o da cauda da lista)
Esquema:
Entrada: um ponteiro para a cauda da lista
Saída: a lista atualizada (com menos um elemento)
PNodo RemoverCauda (PNodo Tail) {
PNodo P = Tail; TailAntProx = NULL; (1) Tail = TailAnt; (2) P = LibertarNodo(P); (3) return Tail; }
Remover um elemento duma lista - o que está no meio da lista (caso geral)
Esquema:
Entrada: um ponteiro para a cabeça da lista
Saída: a lista atualizada (com menos um elemento) PNodo RemoverMeio (PNodo Head, INFO X) {
PNodo P; P = Procurar(Head, X); PAntProx = PProx; (1) PProxAnt = PAnt; (2) P = LibertarNodo(P); (3) return Head; }