forked from kelvins/algorithms-and-data-structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCircularLinkedList.c
104 lines (86 loc) · 3.17 KB
/
CircularLinkedList.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
*
* Lista Ligada com Nó Cabeça, Circular e Ordenada (Implementação Dinâmica)
*
*/
#include <stdio.h>
#include <malloc.h>
typedef int TIPOCHAVE; // Tipo de ID de cada nó da lista
// Estrutura de dados que representa cada nó da lista
typedef struct AUX{
TIPOCHAVE chave;
struct AUX* prox;
}NO, *PONT;
typedef struct{
PONT cab; // Nó cabeça
}LISTA;
void inicializar(LISTA *L){
// Nó cabeça não deixa a lista ficar vazia, também pode ser usado como sentinela
L->cab = (PONT) malloc( sizeof(NO) );
L->cab->prox = L->cab; // Começa apontando para o próprio nó, pois é circular
}
// Como neste método não irá alterar a lista, pode ser passado uma cópia dela e não necessáriamente um ponteiro para ela
PONT buscaSequencial(TIPOCHAVE ch, LISTA L, PONT* ant){
*ant = L.cab; // Sendo uma cópia pode-se usar o ponto (.) no lugar de seta (->), o ant guarda o ponteiro para o nó encontrado
PONT pos = L.cab->prox;
L.cab->chave = ch; // Grava o valor no nó cabeça para ser utilizado como sentinela, será o último a ser comparado
while(pos->chave != ch){
*ant = pos; // Guarda o ponteiro para o nó
pos = pos->prox; // Vai para o próximo nó
}
if( pos != L.cab ) // Se o nó não é o nó cabeça é pq encontrou
return pos; // Retorna o nó
else
return NULL; // Senão não encontrou retorna NULL
}
bool excluir(TIPOCHAVE ch, LISTA *L){
PONT aux, ant;
aux = buscaSequencial(ch, *L, &ant); // Busca o valor para excluir, o ant é passado como endereço de memória, assim a função busca altera ele, guardando o valor anterior
if( aux == NULL ) return false; // Não encontrou
ant->prox = aux->prox; // Nó anterior aponta para o próximo, no caso o próximo que o nó a ser excluído está apontando
free(aux); // Libera a memória
return true;
}
void inserir(TIPOCHAVE ch, LISTA *L){
PONT ant = L->cab; // O ant guarda o ponteiro para o nó anterior
PONT pos = L->cab->prox; // O pos guarda o ponteiro para o atual
while(pos->chave < ch && pos != L->cab){
ant = pos; // Guarda o ponteiro para o nó atual, que será o anterior
pos = pos->prox; // Vai para o próximo nó
}
// Quando encontrou a posição correta na ordem crescente
PONT novo_no = (PONT) malloc( sizeof(NO) ); // Cria um novo nó
novo_no->chave = ch; // Coloca a chave no nó
novo_no->prox = pos; // Aponta para o próximo nó
ant->prox = novo_no; // Nó anterior aponta para o novo nó
}
PONT mostrarLista(LISTA L){
PONT pos = L.cab->prox; // Pos recebe o primeiro elemento depois do nó cabeça
while(pos != L.cab){ // Se não for o nó cabeça, a lista não está vazia
printf("[ %d ]->", pos->chave); // Mostra o valor do nó
pos = pos->prox; // Vai para o próximo nó
}printf("\n");
}
int main(){
LISTA lista;
inicializar(&lista);
inserir(4, &lista);
inserir(6, &lista);
inserir(2, &lista);
inserir(3, &lista);
inserir(1, &lista);
inserir(5, &lista);
mostrarLista(lista);
excluir(2, &lista);
excluir(4, &lista);
excluir(6, &lista);
mostrarLista(lista);
// Exemplo de busca na lista
PONT aux;
int valor = 2;
if( buscaSequencial(valor, lista, &aux) != NULL )
printf("Valor %d encontrado.\n", valor );
else
printf("Valor %d não encontrado.\n", valor);
return 0;
}