La implementación de la tabla de secuencias: la implementación de la tabla de secuencias - Se busca programador
Implementación de lista de enlace simple: implementación de lista de enlace simple - Programador buscado
contenido
3. Inicialización y destrucción
5. Operación en la posición pos.
Siete, imprimir lista enlazada
1. Definición
Se puede ver claramente en el diagrama que tiene un nodo principal, y cada nodo tiene un puntero doble, que apunta al nodo anterior y al nodo siguiente, que se definen de acuerdo con el diagrama
typedef int Datatype;
typedef struct ListNode
{
Datatype data;
struct ListNode* next;
struct ListNode* prev;
}ListNode;
2. Crea un nodo
Cree un nodo de doble puntero, ingrese con un valor y vacíe el doble puntero. Debido a que se usa un nodo en la siguiente inicialización, el nodo de creación se escribe primero.
//创建结点
ListNode* Buynode(int x)
{
ListNode* tmp = (ListNode*)malloc(sizeof(ListNode));
if (tmp==NULL)
{
printf("malloc fail\n");
exit(-1);
}
else
{
tmp->data = x;
tmp->next = NULL;
tmp->prev = NULL;
}
return tmp;
}
3. Inicialización y destrucción
inicialización
Pasamos 0 por el valor del nodo principal (generalmente no tiene mucho sentido). Para entender cuando la lista doblemente enlazada está vacía, es decir, su cabeza apunta a su cola . Y queremos cambiar su puntero principal, por lo que se pasa la dirección del puntero principal y se usa el puntero de segundo nivel para recibirlo.
//初始化
void ListInit(ListNode** phead)
{
assert(phead);
*phead = Buynode(0);
(*phead)->next = *phead;
(*phead)->prev = *phead;
}
destruir
La destrucción es liberar y vaciar cada nodo, y finalmente liberar el nodo principal para completar la destrucción de la lista enlazada.
Nota: No puede comenzar desde el nodo principal, provocará un puntero salvaje y el nodo principal debe liberarse en último lugar. Para guardar el siguiente nodo del nodo de lanzamiento por adelantado, es conveniente actualizar el nodo de lanzamiento.
//销毁
void ListDestroy(ListNode* phead)
{
ListNode* cur = phead->next;
while (cur != phead)
{
ListNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
}
Cuatro, operación de cola
tapón de cola
Esta lista enlazada tiene la gran ventaja de que no necesita atravesar para encontrar la cola, es decir, el nodo anterior al nodo cabeza.
Cree un nuevo nodo, el siguiente del nodo final apunta al nuevo nodo, el siguiente del nuevo nodo apunta al nodo principal, el anterior del nuevo nodo apunta al nodo final y el anterior del último nodo principal apunta al nuevo nodo (este paso es para actualizar el nodo final).
//尾插
void ListPushBack(ListNode* phead, Datatype x)
{
assert(phead);
ListNode* newnode = Buynode(x);
ListNode* tail = phead->prev;
tail->next = newnode;
newnode->next = phead;
newnode->prev = tail;
phead->prev = newnode;
}
eliminación de la cola
Elimine la cola, encuentre la cola directamente, establezca una conexión entre la cola anterior de la cola y el nodo de la cabeza, suelte el nodo de la cola y finalmente déjelo vacío.
//尾删
void ListPopBack(ListNode* phead)
{
assert(phead);
if (phead->next == phead)
{
return NULL;
}
ListNode* tail = phead->prev;
tail->prev->next = phead;
phead->prev = tail->prev;
free(tail);
tail = NULL;
}
5. Operación en la posición pos.
Para insertar y eliminar en una posición fija, primero debe encontrar la posición pos. Primero podemos crear una función de búsqueda para ubicar la pos.
encontrar función
//查找
ListNode* ListFind(ListNode* phead, Datatype x)
{
assert(phead);
ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
inserción de posición pos
Esta inserción es inserción frontal, que se inserta antes de la posición pos. Específicamente , los tres nodos de pos, el anterior a insertar y el pos, están conectados.
//pos位置插入
void ListInsert(ListNode* pos, Datatype x)
{
ListNode* newnode = Buynode(x);
pos->prev->next = newnode;
newnode->next = pos;
newnode->prev = pos->prev;
pos->prev = newnode;
}
borrar posición pos
Esto es más simple, simplemente conecte los dos nodos antes y después de la posición pos y suelte la pos.
//pos位置删除
void ListErase(ListNode* pos)
{
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
pos = NULL;
}
6. Operación de la cabeza
La operación principal es operar el siguiente nodo principal, el nodo principal no cambia, asegúrese de prestar atención a esto.
enchufe de cabeza
Inserte un nodo entre el nodo principal y el siguiente nodo del nodo principal, y actualice la conexión entre los tres nodos. Es lo mismo que la inserción de la posición pos. Podemos simplificar el código y operar directamente con la función ListInsert.
//头插
void ListPushFront(ListNode* phead, Datatype x)
{
assert(phead);
ListInsert(phead->next,x);
}
eliminación de encabezado
Al igual que la operación de eliminación de posición pos, use la función ListErase para operar directamente.
//头删
void ListPopFront(ListNode* phead)
{
assert(phead);
ListErase(phead->next);
}
Al adjuntar la función ListErase y la función ListInsert, es necesario pasar claramente el siguiente nodo principal, y el nodo principal no debe moverse.
Instrucciones complementarias
Dado que la operación principal se puede adjuntar a la función ListErase y la función ListInsert, la operación final, por supuesto, también puede usar la función ListErase y la función ListInsert para simplificar el código.
tapón de cola
Agregar un nodo después de la cola significa agregar un nodo delante del nodo principal. La función ListInsert agrega un nodo antes de pos. Solo necesitamos reemplazar pos con el nodo principal, y luego se puede adjuntar el código simplificado:
//尾插 void ListPushBack(ListNode* phead, Datatype x) { assert(phead); ListInsert(phead, x); }
eliminación de la cola
Eliminar el último nodo es lo mismo que eliminar el nodo de posición pos. Reemplace pos con el nodo de cola para simplificar el código con la función ListErase :
//尾删 void ListPopBack(ListNode* phead) { assert(phead); ListErase(phead->prev); }
Siete, imprimir lista enlazada
Sin imprimir el nodo principal, la impresión puede comenzar desde el siguiente nodo principal:
//打印
void PrintList(ListNode* phead)
{
assert(phead);
ListNode* cur = phead;
cur = cur->next;
while (cur!=phead)
{
printf("%d ",cur->data);
cur=cur->next;
}
}
En este momento, las diversas interfaces funcionales de la lista enlazada circular bidireccional se han realizado. ¡El menú y la función principal se pueden diseñar de acuerdo con sus propias necesidades! ¡Gracias por su apoyo, comentarios y correcciones son bienvenidos!