[Estructura de datos] Implementación de una lista enlazada circular bidireccional (lenguaje c)

Prefacio: las ventajas de la lista doblemente enlazada

Lista enlazada circular bidireccional líder : la estructura más compleja , generalmente utilizada para almacenar datos por separado.

La estructura de datos de la lista enlazada utilizada en la práctica es una lista enlazada circular bidireccional con el líder.

Además, aunque esta estructura es compleja , después de usar el código para implementar, encontrará que la estructura traerá

Son muchas las ventajas, pero la implementación es sencilla , y lo sabremos cuando implementemos el código más adelante.

1. Diagrama para liderar la estructura de la lista doblemente enlazada

Para una lista enlazada individualmente, cada nodo consta de un dato y un puntero, y solo el puntero necesita registrar la dirección del siguiente nodo.

Cada nodo de la lista doblemente enlazada se compone de dos punteros y un dato , uno de los cuales se usa para almacenar la dirección del nodo anterior , y el otro puntero se usa para almacenar la dirección del siguiente nodo , realizando así el lista de enlaces bidireccionales. El diagrama esquemático de la lista doblemente enlazada es el siguiente:

Entre ellos, el puntero anterior se usa para guardar la dirección del nodo anterior, el puntero siguiente se usa para guardar la dirección del siguiente nodo y los datos se usan para guardar los datos.

(1) Tomar la iniciativa en la interfaz de la lista enlazada circular bidireccional

2. Pasos para realizar la lista enlazada

  1. crear e inicializar

Primero, debe definir una estructura y luego debe solicitar espacio en el montón como nodo principal (comúnmente conocido como nodo centinela) y luego conectarlos de extremo a extremo. Como se muestra abajo:

definir una estructura

Asignar espacio para la estructura.

Cuando solicite espacio por primera vez, establezca estos dos punteros en vacío (para evitar punteros salvajes) y luego asigne un valor a los datos

Luego devuelva la dirección del nuevo nodo solicitado

inicialización

Deje que el nódulo principal (nódulo centinela) se apunte a sí mismo para un juicio posterior

  1. Tail plug y tail delete e interfaz de impresión

(1) Inserción de la cola , de la lista enlazada circular (el diagrama al principio), podemos saber que el puntero anterior del nodo principal apunta a la cola de la lista enlazada, deje que el puntero de la cola apunte primero a la cola,

Luego, deje que el anterior del nodo principal apunte a newnode (en este momento, newnode es el nodo final),

Luego deje que el siguiente puntero del nodo de cola original apunte a newnode,

再让newnode的next指针指向头节点(phead)实现循环,

最后让newnode的prev指针指向tail(原来的尾节点)即可

2)尾删前需要判断一下链表是否为空,因此创建一个判断链表是否为空的接口

(3)尾删,用一个指针记录一下尾节点的地址,

然后让尾节点的上一个节点指向头节点,

再让头节点的prev指针指向此时尾节点的上一个节点,

最后把为节点释放掉就好了,

这里我没有让tail指针置空,是因为tail是局部变量,该函数一调用完,该函数的栈帧就会立马

被销毁(tail也被销毁了),所以我觉得没必要(不会发生野指针问题),当然想置空也是可以的

(4)打印接口

这里只需要注意当tail等于头指针时结束遍历即可,因为该链表为循环链表如果没有这个条件将会发生死循环,最后程序会崩掉

3.头插和头删

头插,该链表的头插和链表的头插有点区别,就是需要把新节点插到头节点的后面

让新节点的next指针指向原来的头节点的下一个节点,

让新节点的prev节点指向头节点,

然后让头节点的下一个节点的prev指针指向新节点,

最后让头节点的next指针指向新节点

头删删除链表中的数据肯定先要判断链表是否为空,所以进行了一下断言

定义一个指针first用来保存被删除的节点,

然后让头节点指向被删除节点(first)的下一个节点,

然后再让first指针的下一个节点的prev指针指向头节点

最后把first指向的节点释放掉就好了

  1. 任意元素前的插入和任意元素的删除

任意元素前的插入

让新节点的next指针指向pos节点

然后让新节点的prev指向pos节点的上一个节点

再让新节点的上一个节点(原来pos节点的上一个节点)的next指向新节点

最后让pos节点的prev指针指向新节点

任意元素的删除

先让pos节点的上一个节点的next指针指向pos节点的下一个节点,

然后再让pos节点的下一个节点的prev指针指向pos节点的上一个节点

最后释放掉pos节点,把pos节点置空即可

  1. 元素的查找

查找要找的元素,如果找到就返回该节点,如果找不到就返回NULL

  1. 链表的销毁

把申请的链表给删掉,不过多阐述了

三.一些小技巧

1.任意元素前插入(头插)

当我们在需要在较短的时间内写出一个双向循环链表的时候

可以只写 任意元素前的插入、和任意元素的删除即可

因为当给任意元素前的插入接口传头节点的next指针指向的地址时,相当于头插(如下图)

2.任意元素前插入(尾插)

当给任意元素前的插入接口传plist(头节点)的地址时,相当于尾插(如下图)

因为链表是从plist(头节点)的下一个节点开始遍历,

最后才到头节点

3.任意元素的删除(头删)

当给该接口传头节点的next指针指向的地址时,此时该接口相当于头删,如下图:

4.任意元素的删除(尾删)

给该接口传头节点的prev指针指向的地址时,此时该接口相当尾删,如下图:

今日份享就到这里了,路过的小伙们给个关注和小赞吧,如果有错误也请指出来,让我们共同进步吧(886)!!!

Supongo que te gusta

Origin blog.csdn.net/m0_72532428/article/details/129477992
Recomendado
Clasificación