La estructura de ocho listas enlazadas más detallada y el tutorial de funcionamiento básico de la lista enlazada individualmente

Contenido de este artículo


inserte la descripción de la imagen aquí

1. Lo que Xiaosheng quiere decir

Soy un estudiante de primer año en la escuela, espero que los grandes dioses puedan darme más orientación.. La última vez aprendimos sobre la tabla de secuencias y sus operaciones básicas. Ahora echemos un vistazo a la lista enlazada. Si la encuentra útil, no olvide darle una nota a Xiaosheng, y Xiaosheng continuará actualizándola.¡Vamos, técnico! ! !

2. Conoce la lista enlazada

1. El concepto básico de lista enlazada

Una lista enlazada es una secuencia finita de N elementos de datos,Su longitud se puede aumentar o acortar según sea necesario., al igual que la tabla de secuencia anterior, es un tipo de tabla lineal.Una lista secuencial es una estructura de almacenamiento secuencial, pero una lista enlazada es una estructura de almacenamiento encadenada.
inserte la descripción de la imagen aquí

lista únicaUse el nodo para almacenar los datos y la dirección del siguiente nodo, por lo que el nodo generalmente se divide en varias partes, a saber, el campo de datos y el campo de puntero,El campo de datos almacena datos válidos y el campo de puntero almacena la dirección del siguiente nodo., mientras que una lista con un solo enlace tiene solo un campo de puntero, y una lista doblemente enlazada tiene dos campos de puntero.

2. Comprender la diferencia y las ventajas y desventajas de la lista enlazada simple y la lista secuencial

Estas son dos estructuras de almacenamiento diferentes. Hablemos primero de la diferencia. La tabla secuencial es una estructura de almacenamiento secuencial.Su característica es que dos elementos lógicamente adyacentes entre sí también lo son en posición física.. Pero la lista enlazada es diferente,La característica de la estructura de almacenamiento en cadena es que no requiere elementos lógicamente adyacentes para ser adyacentes en ubicación física.. Porque la estructura de almacenamiento encadenada puede encontrar directamente la ubicación del siguiente nodo a través del campo de puntero en el nodo. inserte la descripción de la imagen aquí
Las ventajas y desventajas de la tabla de secuencia:
1.ventaja: Puede acceder directamente a los datos requeridos a través de subíndices
2. Desventajas:No se puede asignar memoria según sea necesario, solo puede usar la función malloc o realloc para la expansión, fácil de lograr una expansión frecuente,Es fácil causar problemas como el desperdicio de memoria y la fuga de datos..
Ventajas y desventajas de la lista enlazada simple:
1. Ventajas:La longitud de la lista enlazada se puede aumentar o disminuir creando nodos de acuerdo con las necesidades reales, utiliza la memoria en mayor medida.
2. Desventajas:Al insertar o eliminar en la cola o en cualquier posición, la complejidad del tiempo y la complejidad del espacio son relativamente grandes Cada vez, la posición requerida debe encontrarse moviendo el puntero, lo que es menos eficiente que la búsqueda de tabla secuencial.

3. Conoce los ocho tipos de listas enlazadas

Antes de comprender los tipos de listas enlazadas, debemos comprender varias características de las listas enlazadas :
1. Unidireccional y Bidireccional
2. Con plomo y sin plomo
3. Cíclica y Acíclica

Podemos combinarlos, como: lista enlazada circular principal unidireccional, lista enlazada no circular no principal bidireccional...
Xiaosheng dibuja algunas imágenes para que todos lo sepan

~~Lista enlazada circular unidireccional con encabezado

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~Lista enlazada acíclica con encabezado unidireccional

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~Lista enlazada circular unidireccional sin plomo

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

~~ Lista unidireccional enlazada acíclica sin plomo

inserte la descripción de la imagen aquí

inserte la descripción de la imagen aquí

~~ Lista enlazada circular con encabezado bidireccional

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~ Lista enlazada acíclica de dos cabezas

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~ Lista enlazada circular bidireccional sin cabeza

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~ Lista enlazada acíclica sin plomo bidireccional

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2. Funcionamiento básico de la lista enlazada simple

La lista de enlaces simples a la que nos referimos a continuación es una lista de enlaces acíclicos sin plomo

1. Interfaz para operaciones básicas (básico)

La lista de enlace único es similar a la lista secuencial. La adición, eliminación, modificación y verificación son las operaciones básicas en la lista de enlace único. ¡Echemos un vistazo a la interfaz básica primero!

inserte la descripción de la imagen aquí

2. Definición de la estructura de la lista enlazada simple

Los nodos de una lista enlazada individualmente se dividen en dos partes, el campo de datos y el campo de puntero . Entonces podemos definir un nodo con la siguiente estructura

typedef int SLTDataType;
typedef struct SListNode
{
    
    
	SLTDataType data;
	struct SListNode* pNext;
}SLTNODE;

3. Creación de nodos

Debido a que la longitud de la lista enlazada aumenta posteriormente, la creación de un nodo es, hasta cierto punto, la primeraCree una variable del tipo de puntero de estructura, inicialícela y finalmente devuelva la variable, podemos analizar directamente a través del código. Primero veamos la creación de una lista enlazada con nodos principales

SLTNODE* CreateNode(SLTDataType val)
{
    
    
	SLTNODE* pNew = (SLTNODE*)malloc(sizeof(SLTNODE));
	pNew->data = val;
	pNew->pNext = NULL;
	return pNew;
}

4. Distinguir la transmisión del puntero de primer nivel y el puntero de segundo nivel

Si desea cambiar el puntero principal de la lista vinculada, debe pasar el puntero de segundo nivel. Cambiar el puntero principal no puede pasar el puntero de primer nivel porque el proceso de transferencia es el proceso de copia, que es equivalente a copiar el puntero principal. El cambio del parámetro formal no afectará al parámetro real. Por lo tanto, para cambiar el puntero principal de la lista enlazada, es necesario transferir el puntero secundario.

5. Inserción de una lista enlazada simple

~~ El encabezado de la lista enlazada individualmente

Debido a que enfatizamos anteriormente,La lista de enlaces simples en la que operamos no tiene un nodo principal, por lo que el complemento de la cabeza es muy conveniente. En cuanto a cómo operar la lista de enlaces únicos con el nodo de la cabeza, también es muy simple. Creo que los grandes dioses pueden escribirlo por sí mismos.

//因为要改变头指针所以我们要传送头指针的地址,即二级结构体指针变量
 void SListPushFront(SLTNODE** ppHead, SLTDataType val)
{
    
    
	
	SLTNODE* pNew  = CreateNode(val);
	pNew->pNext = *ppHead;
	*ppHead = pNew;
}

~~Inserción de cola de una lista enlazada individualmente

Al insertar la cola, debemos considerar si la lista enlazada de forma individual está vacía , porque si está vacía, debemos apuntar el puntero de la cabeza al nuevo nodo.

void SListPushBack(SLTNODE** ppHead, SLTDataType val)
{
    
    
	SLTNODE* pNew = CreateNode(val);
	//判断链表是否为空,若为空则将头指针指向新结点
	if (*ppHead == NULL)
	{
    
    
		*ppHead = pNew;

	}
	else
	{
    
    
		SLTNODE* pTail = *ppHead;
		//通过循环让指针找到尾部
		while (pTail->pNext != NULL)
		{
    
    
			pTail = pTail->pNext;
		}
		pTail->pNext = pNew;
	}
	
}

Me pregunto si los dioses han notado que la condición de nuestro bucle es pTail->pNext != NULL, ¿puede cambiarse a pTail != NULL? A primera vista, parece que no hay problema, pero ¿realmente no hay problema? Pensemos en ello~

Veamos primero la condición de bucle correcta pTail->pNext != NULL

Por conveniencia, usamos pHead en lugar de *ppHead en la figurainserte la descripción de la imagen aquíEn este momento, se establece pTail->pNext != NULL y el puntero pTail se mueve hacia atrás inserte la descripción de la imagen aquíEn este momento, se establece pTail->pNext != NULL y el puntero pTail se mueve hacia atrás
inserte la descripción de la imagen aquí
Tenga en cuenta que no hay ningún nodo detrás en este momento, entonces el nodo al que apunta pTail en este momento está dentro. El campo de puntero almacena un puntero nulo, es decir, pTail->pNext está vacío, y pTail solo apunta al último nodo . Echemos un vistazo al caso donde la condición del ciclo es pTail != NULL.
inserte la descripción de la imagen aquí
En este momento, se establece pTail != NULL. Cuando el puntero pTail se mueve hacia atrás,
inserte la descripción de la imagen aquí
pTail != NULL todavía se establece. Cuando se mueve el puntero pTail hacia atrás,
inserte la descripción de la imagen aquí
pTail != NULL todavía está establecido.Después del desplazamiento del puntero pTail
inserte la descripción de la imagen aquí
De lo anterior, podemos encontrar que cuando se ejecuta la condición de pTail != NULL, no se detendrá cuando pTail apunte al nodo de cola , por lo que la condición del ciclo es incorrecta

~~Insertar en la posición especificada de la lista enlazada individualmente

~~ insertar antes de la posición pos

Aquí tenemos dos casos,pos es el primer nodo y pos no es el primer nodo. Si pos es 1, es equivalente a la inserción de encabezado. Si pos no es 1, use dos punteros para encontrar el nodo anterior de pos y pos a través de un bucle.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

void SListInsert(SLTNODE** ppHead, SLTNODE* pos, SLTDataType val)
{
    
    
	//1.pos是第一个结点,在pos之前插入相当于头插
	if (*ppHead == pos)
	{
    
    
		SListPushFront(ppHead, val);
	}
	//2.pos不是第一个结点
	SLTNODE* pPrev = NULL;
	SLTNODE* pMove = *ppHead;
	while (pMove != pos)
	{
    
    
		pPrev = pMove;
		pMove = pMove->pNext;
	}
	SLTNODE* pNew = CreateNode(val);
	pPrev->pNext = pNew;
	pNew->pNext = pos;
}

Aquí usamos dos punteros, podemos pasarun puntero¿Se implementa directamente? intentemos

void SListInsert(SLTNODE** ppHead, SLTNODE* pos, SLTDataType val)
{
    
    
	if (*ppHead == pos)
	{
    
    
		SListPushFront(ppHead, val);
	}
	 SLTNODE* pPrev = *ppHead;
	 while(pPrev->pNext != pos)
	 {
    
    
		  pPrev = pPrev->pNext;
	 }
	 SLTNODE* pNew = CreateNode(SLTDataType val);
	 pPrev->pNext = pNew;
	 pNew->pNext = pos;
	
	SLTNODE* pNew = CreateNode(val);
	pPrev->pNext = pNew;
	pNew->pNext = pos;
}

Obviamente puede,Debido a que se ha determinado el puntero pos, no es necesario buscar la cola como en la inserción anterior de la cola, sino que solo es necesario encontrar el nodo antes de pos.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

~~ insertar después de la posición pos

Una lista enlazada individualmente puede encontrar el siguiente nodo a través del nodo anterior, pero no puede encontrar el nodo anterior a través del último nodo.. Por lo tanto, cuando se inserta después de la posición pos, no hay necesidad de encontrar el nodo a través del movimiento circular del puntero cuando se inserta antes de la posición pos, porque el siguiente nodo se puede encontrar directamente a través de pos

 void SListInsertAfter(SLTNODE * pos, SLTDataType val)
{
    
    
	assert(pos);
	SLTNODE* pNew = CreateNode(val);
	pNew->pNext = pos->pNext;
	pos->pNext = pNew;
}

6. Eliminación de una lista enlazada individualmente

La eliminación y la inserción son similares hasta cierto punto, y se pueden comparar por analogía~~~

~~Eliminar el encabezado de la lista enlazada individualmente

Suelte el primer nodo original y mueva el puntero de la cabeza al siguiente nodoinserte la descripción de la imagen aquí >inserte la descripción de la imagen aquí

void SListPopFront(SLTNODE** ppHead)
{
    
    
	assert(*pHead);
	SLTNODE* next =  (*ppHead)->pNext;
	free(*ppHead);
	*ppHead = next;

}

~~ Eliminación de la cola de la lista enlazada individualmente

Hay tres casos a considerar cuando se elimina la cola ,Si la lista vinculada está vacía, la lista vinculada tiene solo un nodo y la lista vinculada tiene varios nodos

void SListPopBack(SLTNODE** ppHead)
{
    
    
	//1.链表为空
	assert(*ppHead);
	//2.只有一个结点
	if ((*ppHead)->pNext == NULL)
	{
    
    
		free(*ppHead);
		*ppHead = NULL;
	}
	//3.有两个及以上的结点
	SLTNODE* pPrev = NULL;
	SLTNODE* pTail = *ppHead;
	while (pTail->pNext != NULL)
	{
    
    
		pPrev = pTail;
		pTail = pTail->pNext;
	}
	free(pTail);
	pPrev->pNext = NULL;
}

~~Eliminar la posición especificada de la lista enlazada individualmente

Cuando pos es igual al puntero de la cabeza, es equivalente a la eliminación de la cabeza de la lista enlazada.Podemos llamar directamente a la función de eliminación de la cabeza SListPopFront() escrita anteriormente.

void SListErase(SLTNODE** ppHead,SLTNODE* pos)
{
    
    
	if (pos == *ppHead)
	{
    
    
		SListPopFront(*ppHead);
	}
	else
	{
    
    
		SLTNODE* pPrev = *ppHead;
		while (pPrev->pNext != pos)
		{
    
    
			pPrev = pPrev->pNext;
		}
		pPrev->pNext = pos->pNext;
		free(pPrev);
	}
}

7. Búsqueda de lista enlazada individualmente

Encuentre el nodo que almacena los datos correspondientes en el campo de datos moviendo el puntero continuamente y devuelva el puntero

SLTNODE* SListFind(SLTNODE* pHead,SLTDataType val)
{
    
    
	SLTNODE* pMove = pHead;
	while (pMove != NULL) //while(pMove)
	{
    
    
		if (pMove->data == val)
		{
    
    
			return pMove;
		}
	}
	return NULL;
}

8. Destrucción de una lista enlazada simple

La operación de destrucción debería ser la más fácil, Xiaosheng no será prolijo, creo que los dioses lo entenderán de un vistazo.

 void SListDestroy(SLTNODE** pphead)
{
    
    
	SLTNODE* pMove = *pphead;
	while (pMove !=NULL)
	{
    
    
		SLTNODE* next = pMove->pNext;
		free(pMove);
		pMove = next;
	}

	*pphead = NULL;
}

4. Conclusión

Estoy muy agradecido con los grandes dioses por poder ver esto. Xiaosheng quisiera agradecer a todos aquí. Xiaosheng llevó a todos a una comprensión aproximada de la estructura de ocho listas vinculadas y las operaciones básicas de una sola lista vinculada. No es fácil codificar palabras, y no es fácil ser original. ! ! En el próximo artículo, entraremos en la lista doblemente enlazada y la lista circular enlazada, vamos técnicos (no olviden dar me gusta y seguir) ~~~
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_59955115/article/details/123588720
Recomendado
Clasificación