Estructura de datos: lista doblemente enlazada

Preferiría confiar en mi propia fuerza para abrir mi futuro que buscar el favor de los poderosos. 

Directorio de artículos

El nombre de la función o el nombre de la variable de cada interfaz de la lista enlazada de doble cable. 

Código fuente de implementación de interfaz de lista doblemente enlazada

Índice rápido [archivos de encabezado y declaraciones de funciones]

Implementación de interfaz de lista doblemente enlazada

Análisis de construcción de lista doblemente enlazada

Definición e inicialización de lista doblemente enlazada.

Inserción y eliminación de lista doblemente enlazada.


Revisión anterior:

Estructura de datos: lista enlazada individualmente

Estructura de datos: lista de secuencias

  Hola a todos, soy Ji Ning.

  Este artículo le presenta una lista vinculada con mejor rendimiento que una lista vinculada única: una lista doblemente vinculada, que puede implementar de manera más eficiente la inserción, eliminación y búsqueda de datos.

  La primera mitad del artículo es el nombre correspondiente y el código fuente de la lista doblemente enlazada, y la segunda mitad del artículo es una explicación específica de la implementación de la lista doblemente enlazada.

El nombre de la función o el nombre de la variable de cada interfaz de la lista enlazada de doble cable. 

LTDTipo de datos Cambio de nombre del tipo de datos de lista doblemente enlazada
ListaNodo estructura de lista doblemente enlazada
LTNodo Cambio de nombre de lista doblemente enlazada
ComprarLTNode crear un nodo
LTI inicializar nodo
LTImprimir imprimir lista doblemente enlazada
LTPushBack enchufe de cola
LTPopVolver eliminar cola
LTPushFrontal enchufar
LTPopFrente eliminar cabeza
Tamaño LT Calcular el número de elementos de la lista doblemente enlazados
LTBuscar Buscar elementos de la lista vinculada
LTInsertar insertar nodo antes de pos
LTErasa Eliminar el nodo en la posición pos

Código fuente de implementación de interfaz de lista doblemente enlazada

Índice rápido [archivos de encabezado y declaraciones de funciones]

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;//重命名

typedef struct ListNode
{
	LTDataType Data;
	struct ListNode* next;
	struct ListNode* prev;
}LTNode;
LTNode* BuyLTNode(LTDataType x); //创建一个新节点
LTNode* LTInit(); //哨兵位的头结点
void LTPrint(LTNode*phead);//打印双链表
void LTPushBack(LTNode* phead, LTDataType x);//尾插
void LTPopBack(LTNode* phead);//尾删
void LTPushFront(LTNode* phead, LTDataType x);//头插
void LTPopFront(LTNode* phead);//头删
LTNode* LTFind(LTNode* phead, LTDataType x);//寻找结点
void LTInsert(LTNode*phead,LTNode* pos, LTDataType x); //在pos之前插入结点

Implementación de interfaz de lista doblemente enlazada

LTNode* BuyLTNode(LTDataType x)
{
	LTNode* nownode =(LTNode*)malloc(sizeof(LTNode));
	if (nownode == NULL)
	{
		perror("malloc fail");
	}
	nownode->Data = x;
	nownode->next = NULL;
	nownode->prev = NULL;
	return nownode;
}

LTNode* LTInit()
{
	LTNode* phead = BuyLTNode(0);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* tail = phead->prev;
	LTNode* nownode = BuyLTNode(x);
	nownode->next = phead;
	nownode->prev = tail;
	tail->next = nownode;
	phead->prev = nownode;
}

void LTPrint(LTNode* phead)
{
	assert(phead);
	printf("phead<=>");
	LTNode* cur = phead;
	while (cur->next!=phead)
	{
		printf("%d<=>", cur->next->Data);
		cur = cur->next;
	}
	printf("\n");
}

void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);//只有哨兵位的时候不能删
	LTNode* tail = phead->prev;
	LTNode* tailPrev = tail->prev;
	tailPrev->next = tail->next;
	phead->prev = tailPrev;
	free(tail);
}
void LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* first = phead->next;
	LTNode* nownode = BuyLTNode(x);
	nownode->next = first;
	nownode->prev = phead;
	phead->next = nownode;
	first->prev = nownode;
}

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);//只有哨兵位的时候不能删除
	LTNode* first = phead->next;
	LTNode* second = first->next;
	phead->next = second;
	second->prev = phead;
	free(first);
}

LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* cur = phead;
	while (cur->next != phead)
	{
		if (cur->next->Data == x)
			return  cur->next;
		cur = cur->next;
	}
	return NULL;
}

void LTInsert(LTNode* phead, LTNode* pos, LTDataType x)
{
	assert(phead);
	assert(pos);
	LTNode* cur = phead;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	LTNode*nownode = BuyLTNode(x);
	nownode->next = pos;
	nownode->prev = cur;
	cur->next = nownode;
	pos->prev = nownode;
}

void LTErase(LTNode* phead, LTNode* pos)
{
	assert(pos&&phead);
	assert(pos->next != pos);
	assert(phead->next != phead);
	LTNode* cur = phead;
	LTNode* posNext = pos->next;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	cur->next = posNext;
	posNext->prev = cur;
	free(pos);
}

Análisis de construcción de lista doblemente enlazada

  Lista doblemente enlazada, en comparación con la lista simple enlazada, el nodo de la lista doblemente enlazada tiene dos dominios de puntero, uno apunta al siguiente nodo y el otro apunta al nodo anterior; la lista doblemente enlazada predeterminada tiene un nodo principal con un bit centinela. la cabeza del bit centinela El nodo almacena la dirección del primer nodo válido (phead->next) y la dirección del último nodo válido (phead->prev).

Comparación de diagramas lógicos de listas enlazadas simples y dobles

Comparación de diagramas físicos de listas simple y doblemente enlazadas.

Definición e inicialización de lista doblemente enlazada.

  Hay un campo de datos y dos campos de puntero en la lista doblemente enlazada, un puntero apunta a la dirección del siguiente nodo y el otro puntero a la dirección del nodo anterior, y la estructura de la lista doblemente enlazada cambia de nombre nuevamente.

  Cuando una lista doblemente enlazada abre un nuevo nodo, primero necesita abrir un espacio del tamaño de un nodo, señalar su siguiente y NULL para vaciar, y luego asignar el valor de su campo de datos a x.

Inserción y eliminación de lista doblemente enlazada.

  Para eliminar la lista doblemente enlazada, lo primero que hay que tener claro es que el nodo cabeza del bit centinela no se puede eliminar, porque es el soporte estructural de toda la lista doblemente enlazada. Al eliminar, busque el nodo anterior y el siguiente nodo del nodo que desea eliminar, apunte el siguiente puntero del nodo anterior al siguiente nodo y apunte el puntero anterior del siguiente nodo al nodo anterior. Finalmente, se libera el espacio del nodo eliminado.

  La inserción de una lista doblemente enlazada, al insertar, teóricamente puede insertar un nodo en cualquier posición. Porque en el momento de la inicialización, los campos de puntero que definen los nodos recién creados están todos vacíos. Por lo tanto, al insertar, es necesario cambiar los dos campos de puntero del nodo insertado, apuntar su puntero siguiente al siguiente nodo y hacer que su puntero anterior apunte al nodo anterior. De manera similar, apunte el puntero siguiente del nodo anterior a este nuevo nodo y apunte el puntero anterior del puntero siguiente a este nuevo nodo.

Supongo que te gusta

Origin blog.csdn.net/zyb___/article/details/132063876
Recomendado
Clasificación