Implementación de una lista enlazada doblemente circular con encabezado

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

1. Definición

2. Crea un nodo

3. Inicialización y destrucción

inicialización

destruir

Cuatro, operación de cola

tapón de cola

eliminación de la cola

5. Operación en la posición pos.

encontrar función

inserción de posición pos

borrar posición pos

6. Operación de la cabeza

enchufe de cabeza

eliminación de encabezado

 Instrucciones complementarias

tapón de cola

eliminación de la cola

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!

 

Supongo que te gusta

Origin blog.csdn.net/weixin_53316121/article/details/123711969
Recomendado
Clasificación