Lista enlazada circular: ventajas y desventajas
โก Resumen inteligente
Las listas enlazadas circulares organizan los nodos de manera que el รบltimo nodo vuelva al primero, lo que proporciona una estructura continua y sin valores nulos que se adapta a la programaciรณn round-robin, los anillos de tokens y cualquier flujo de trabajo que necesite un recorrido sin interrupciones.
ยฟQuรฉ es una lista enlazada circular?
Una lista enlazada circular es una secuencia de nodos dispuestos de manera que cada nodo pueda ser...traccada โnodoโ es un elemento autorreferencial con punteros a uno o dos nodos en su proximidad inmediata.
A continuaciรณn se muestra una representaciรณn de una lista enlazada circular con 3 nodos.
Aquรญ, puedes ver que cada nodo es retraccapaz de sรญ misma. El ejemplo que se muestra arriba es una lista enlazada simple circular.
Nota: La lista enlazada circular mรกs simple es un รบnico nodo cuyo puntero siguiente tracvuelve a sรญ mismo, como se muestra a continuaciรณn.
Bรกsico Operaciones en listas enlazadas circulares
Las tres operaciones bรกsicas en una lista enlazada circular son:
- Inserciรณn
- Eliminaciรณn y
- Travesรญa
- La inserciรณn es el proceso de colocar un nodo en una posiciรณn especรญfica en la lista circular enlazada.
- La eliminaciรณn es el proceso de eliminar un nodo existente de la lista vinculada. El nodo puede identificarse por la apariciรณn de su valor o por su posiciรณn.
- El recorrido de una lista enlazada circular es el proceso de mostrar todo el contenido de la lista enlazada y volver a mostrarlo.tracvolviendo al nodo de origen.
La siguiente secciรณn explica cรณmo funciona la inserciรณn y los dos tipos de inserciรณn posibles en una lista circular enlazada simple.
Inserciรณn Operadisrupciรณn
Primero, crea un nodo cuyo puntero next apunte a sรญ mismo, como se muestra a continuaciรณn. Sin este nodo semilla, la primera inserciรณn se convierte en el primer nodo de la lista.
A continuaciรณn, existen dos posibilidades:
- Inserciรณn en la posiciรณn actual de la lista enlazada circular. Esto equivale a insertar un elemento al principio o al final de una lista enlazada simple regular; en una lista enlazada circular, el principio y el final coinciden.
- Inserciรณn despuรฉs de un nodo indexado. El nodo debe identificarse mediante un nรบmero de รญndice correspondiente al valor de su elemento.
Para insertar un nodo al principio o al final de la lista enlazada circular, es decir, en la posiciรณn donde se agregรณ el primer nodo, siga los pasos que se indican a continuaciรณn:
- Tendrรกs que romper el autovรญnculo existente con el nodo existente.
- El siguiente puntero del nuevo nodo se vincularรก al nodo existente.
- El siguiente puntero del รบltimo nodo apuntarรก al nodo insertado.
NOTA: El puntero que marca el inicio o el final del cรญrculo se puede reasignar a cualquier nodo. El recorrido seguirรก devolviendo al mismo nodo, como se explica mรกs adelante en este artรญculo.
Los pasos en (a) i-iii se muestran a continuaciรณn:
(Nodo existente)
Paso 1) Romper el enlace existente
Paso 2) Crear un enlace directo (desde un nuevo nodo a un nodo existente)
Paso 3) Crear un enlace de bucle al primer nodo.
A continuaciรณn, intentarรก la inserciรณn despuรฉs de un nodo.
Por ejemplo, inserte โVALUE2โ despuรฉs del nodo que contiene โVALUE0โ, suponiendo que el punto de partida es el nodo con โVALUE0โ.
- Rompe el vรญnculo entre el primer y el segundo nodo, y coloca el nodo con โVALUE2โ en medio.
- El puntero siguiente del primer nodo apunta al nuevo nodo, y el puntero siguiente del nuevo nodo apunta a lo que antes era el segundo nodo.
- El resto de la disposiciรณn permanece sin cambios. Todos los nodos son retraccapaces de hacerlo por sรญ mismos.
NOTA: Debido a que la disposiciรณn es cรญclica, el procedimiento para insertar un nodo es idรฉntico independientemente de la posiciรณn que se elija. El puntero que cierra el ciclo se comporta como cualquier otro puntero de la lista.
Esto se muestra a continuaciรณn:
(Digamos que sรณlo hay dos nodos. Este es un caso trivial)
Paso 1) Retire el enlace interno entre los nodos conectados.
Paso 2) Conecte el nodo del lado izquierdo al nuevo nodo
Paso 3) Conecte el nuevo nodo al nodo del lado derecho.
Eliminacion Operadisrupciรณn
Supongamos una lista enlazada circular de 3 nodos. Los dos casos de eliminaciรณn son:
- Eliminar el elemento actual
- Eliminaciรณn despuรฉs de un elemento.
Eliminaciรณn al principio/final:
- Atraviese hasta el primer nodo desde el รบltimo nodo.
- Eliminar elementos desde el final requiere solo un paso de recorrido, desde el รบltimo nodo hasta el primero.
- Elimine el enlace entre el รบltimo nodo y el primer nodo.
- Vincula el รบltimo nodo al siguiente elemento del primer nodo.
- Libera el primer nodo.
(Configuraciรณn existente)
Paso 1) Eliminar el enlace circular
Paso 2) Eliminar el vรญnculo entre el primero y el siguiente, vincular el รบltimo nodo al nodo siguiente al primero.
Paso 3) Liberar/desasignar el primer nodo
Eliminaciรณn despuรฉs de un nodo:
- Recorre la lista hasta que el siguiente nodo sea el que se va a eliminar.
- Vaya al siguiente nodo y coloque un puntero en el nodo anterior.
- Conecte el nodo anterior al nodo posterior al nodo actual, utilizando su puntero siguiente.
- Libere el nodo actual (desvinculado).
Paso 1) Digamos que necesitamos eliminar un nodo con "VALOR1".
Paso 2) Elimine el vรญnculo entre el nodo anterior y el nodo actual, luego vincule el nodo anterior directamente al nodo al que apunta el puntero siguiente del nodo actual (el nodo despuรฉs de VALUE1).
Paso 3) Liberar o desasignar el nodo actual.
Recorrido de una lista enlazada circular
Para recorrer una lista enlazada circular desde el รบltimo puntero, primero compruebe si este es nulo. Si no lo es, verifique si la lista tiene un solo elemento. De lo contrario, recorra la lista con un puntero temporal hasta llegar nuevamente al รบltimo puntero, como se muestra en la animaciรณn a continuaciรณn.
Ventajas de la lista enlazada circular
Algunas de las ventajas de las listas enlazadas circulares son:
- No se requiere una asignaciรณn NULL en el cรณdigo. La lista circular nunca apunta a un puntero NULL a menos que se desasigne por completo.
- Las listas enlazadas circulares son ventajosas para las operaciones de final de lista porque el principio y el final coinciden. Algorithms Los mรฉtodos de planificaciรณn como round-robin pueden recorrer los procesos en cola de forma limpia, sin encontrar punteros colgantes o nulos.
- Una lista enlazada circular aรบn admite todas las operaciones regulares de una lista enlazada simple. lista doblemente enlazada Incluso puede eliminar la necesidad de recorrer toda la lista para localizar un elemento; en el peor de los casos, el objetivo se encuentra frente al puntero de inicio, por lo que como mรกximo es necesario recorrer la mitad de la lista.
Desventajas de la lista enlazada circular
Las desventajas de utilizar una lista enlazada circular se encuentran a continuaciรณn:
- Las listas circulares son mรกs complejas que listas enlazadas individualmente.
- RevInvertir una lista circular es mรกs complejo que invertir una lista enlazada simple o doble.
- Si la terminaciรณn del bucle no se maneja con cuidado, el cรณdigo de recorrido puede entrar en un bucle infinito.
- Es mรกs difรญcil encontrar el final de la lista y escribir las condiciones de control de bucle correctas.
- Insertar al principio requiere recorrer toda la lista para llegar al รบltimo nodo (desde una perspectiva de implementaciรณn).
Lista enlazada individualmente como lista enlazada circular
Le recomendamos leer e implementar el cรณdigo C que aparece a continuaciรณn. Este cรณdigo ilustra la aritmรฉtica de punteros asociada a una lista enlazada simple circular.
#include<stdio.h> #include<stdlib.h> struct node { int item; struct node *next; }; struct node* addToEmpty(struct node*,int); struct node *insertCurrent(struct node *, int); struct node *insertAfter(struct node *, int, int); struct node *removeAfter(struct node *, int); struct node *removeCurrent(struct node *); void peek(struct node *); int main() { ...
Explicaciรณn del cรณdigo:
- Las dos primeras lรญneas de cรณdigo son los archivos de encabezado necesarios incluidos.
- La siguiente secciรณn define la estructura de cada nodo autorreferencial. Contiene un valor y un puntero del mismo tipo que la estructura.
- Cada instancia de estructura se vincula con otros objetos de estructura del mismo tipo.
- Existen diferentes prototipos de funciones para:
- Agregar un elemento a una lista enlazada vacรญa
- Insertando en el actualmente apuntado Posiciรณn de una lista circular enlazada.
- Insertar despuรฉs de un particular indexado valor en la lista vinculada.
- Quitar/eliminar despuรฉs de un particular indexado valor en la lista vinculada.
- Eliminar en la posiciรณn actual de una lista enlazada circular
- La รบltima funciรณn imprime cada elemento a travรฉs de un recorrido circular en cualquier estado de la lista vinculada.
int main() { struct node *last = NULL; last = insertCurrent(last,4); last = removeAfter(last, 4); peek(last); return 0; } struct node* addToEmpty(struct node*last, int data) { struct node *temp = (struct node *)malloc(sizeof( struct node)); temp->item = data; last = temp; last->next = last; return last; } struct node *insertCurrent(struct node *last, int data)
Explicaciรณn del cรณdigo:
- Para el cรณdigo addToEmpty, asigne un nodo vacรญo utilizando la funciรณn malloc().
- Coloque los datos entrantes en el nodo temporal.
- Asigne el nodo temporal al รบltimo nodo y establezca su puntero siguiente hacia sรญ mismo, de modo que el nodo รบnico apunte de nuevo hacia sรญ mismo.
- Devuelve el รบltimo puntero al contexto principal de la aplicaciรณn.
struct node *insertCurrent(struct node *last, int data) { if(last == NULL) { return addToEmpty(last, data); } struct node *temp = (struct node *)malloc(sizeof( struct node)); temp -> item = data; temp->next = last->next; last->next = temp; return last; } struct node *insertAfter(struct node *last, int data, int item) { struct node *temp = last->next, *prev = temp, *newnode =NULL; …
Explicaciรณn del cรณdigo
- Si la lista estรก vacรญa, pase el control a addToEmpty() y devuelva el control.
- Crea un nodo temporal para colocarlo despuรฉs del nodo actual.
- Conecte los punteros como se muestra en el diagrama anterior.
- Devuelve el รบltimo puntero, que coincide con el patrรณn utilizado en la funciรณn anterior.
... struct node *insertAfter(struct node *last, int data, int item) { struct node *temp = last->next, *prev = temp, *newnode =NULL; if (last == NULL) { return addToEmpty(last, item); } do { prev = temp; temp = temp->next; } while (temp->next != last && temp->item != data ); if(temp->item != data) { printf("Element not found. Please try again"); ...
Explicaciรณn del cรณdigo:
- Si la lista estรก vacรญa, ignore la clave de bรบsqueda, agregue el elemento actual como el รบnico nodo en la lista y devuelva el control.
- En cada iteraciรณn del bucle do-while, un puntero anterior almacena el รบltimo resultado recorrido.
- Solo entonces se produce el siguiente paso del recorrido.
- El bucle do-while finaliza cuando se encuentran los datos de destino o cuando temp vuelve a alcanzar el รบltimo puntero. El siguiente bloque de cรณdigo decide quรฉ hacer con el elemento encontrado.
...
if(temp->item != data)
{
printf("Element not found. Please try again");
return last;
}
else
{
newnode = (struct node *)malloc(sizeof(struct node));
newnode->item = item;
prev->next = newnode;
newnode->next = temp;
}
return last;
}
struct node *removeCurrent(struct node *last)
...
Explicaciรณn del cรณdigo:
- Si se ha recorrido toda la lista pero no se encuentra el elemento, muestre un mensaje de "Elemento no encontrado" y devuelva el control a quien realizรณ la llamada.
- Si se encuentra el nodo de destino, asigne un nuevo nodo para insertar el valor.
- Enlace el nodo anterior al nuevo nodo, y vincular el puntero siguiente del nuevo nodo a temp (la variable de recorrido).
- Esto coloca el nuevo elemento inmediatamente despuรฉs del nodo de destino en la lista enlazada circular. A continuaciรณn, el control regresa a quien realizรณ la llamada.
struct node *removeCurrent(struct node *last) { if(last == NULL) { printf("Element Not Found"); return NULL; } struct node *temp = last->next; last->next = temp->next; free(temp); return last; } struct node *removeAfter(struct node *last, int data)
Explicaciรณn del cรณdigo
- Para eliminar el รบltimo nodo (el actual), primero compruebe si la lista estรก vacรญa. Si lo estรก, no se puede eliminar ningรบn elemento.
- La variable temporal avanza un enlace.
- Vincula el รบltimo puntero al nodo siguiente al primer nodo.
- Libere el puntero temporal para desasignar el nodo no vinculado.
struct node *removeAfter(struct node *last,int data) { struct node *temp = NULL,*prev = NULL; if (last == NULL) { printf("Linked list empty. Cannot remove any element\n"); return NULL; } temp = last->next; prev = temp; do { prev = temp; temp = temp->next; } while (temp->next != last && temp->item != data ); if(temp->item != data) { printf("Element not found"); ...
Explicaciรณn del cรณdigo
- Al igual que con la funciรณn de eliminaciรณn anterior, primero compruebe si la lista estรก vacรญa. Si lo estรก, no se puede eliminar ningรบn elemento.
- Dos punteros Se asignan posiciones especรญficas para localizar el elemento a eliminar.
- Los punteros avanzan uno tras otro (temperatura de los senderos anteriores).
- El recorrido continรบa hasta que se encuentra el elemento de destino o el siguiente puntero vuelve a alcanzar el รบltimo nodo.
if(temp->item != data) { printf("Element not found"); return last; } else { prev->next = temp->next; free(temp); } return last; } void peek(struct node * last) { struct node *temp = last; if (last == NULL) { return;
Explicaciรณn del programa
- Si se recorre toda la lista enlazada sin encontrar el elemento deseado, se muestra un mensaje de "Elemento no encontrado".
- De lo contrario, el elemento se desvincula y se libera en los pasos 3 y 4.
- El puntero anterior estรก vinculado al nodo al que apunta el siguiente puntero de temp (el nodo que sigue al que se estรก eliminando).
- A continuaciรณn, se libera el puntero temporal.
... void peek(struct node * last) { struct node *temp = last; if (last == NULL) { return; } if(last -> next == last) { printf("%d-", temp->item); } while (temp != last) { printf("%d-", temp->item); temp = temp->next; } }
Explicaciรณn del cรณdigo
- El recorrido de exploraciรณn no es posible si no hay nodos; el usuario primero debe asignar o insertar un nodo.
- Si solo hay un nodo, no es necesario recorrerlo: el contenido del nodo se imprime directamente y el bucle while no se ejecuta.
- Si hay mรกs de un nodo, la funciรณn temp imprime todos los elementos hasta el รบltimo.
- En el momento en que se alcanza el รบltimo elemento, el bucle termina y la funciรณn devuelve el control a main().
Aplicaciones de la Lista Enlazada Circular
- Implementaciรณn de programaciรณn por turnos en procesos del sistema y programaciรณn circular en grรกficos de alta velocidad.
- Planificaciรณn mediante anillo de tokens en redes informรกticas.
- Se utiliza en unidades de visualizaciรณn, como por ejemplo en paneles digitales para tiendas, que requieren un desplazamiento continuo de datos.





























