目前,我们了解到的链表,无论是动态链表还是静态链表,表中的每个节点仅包含一个指针(游标),并且全部指向直接后继节点,即通常称为单向链表(或单链表).
尽管使用单链接列表可以100%解决逻辑上“”关系的数据存储问题,但是当解决某些特殊问题时,单链接列表并不是最有效的存储结构. 例如,如果算法需要查找指定节点的大量前任节点,则单链接列表的使用无疑是灾难性的
为了能够有效解决类似问题,在本节中,我们将研究双向链表(简称双链表).
从名称中了解双向链表,即链表是“双向”的,如图1所示:
图1双向链表的原理图
双向的,指的是节点之间的逻辑关系是双向的,但是通常除非实际情况需要,否则仅设置头指针.
从图1中可以看到,双向链接列表中的每个节点包含以下3部分信息(如图2所示): 指针字段: 用于指向当前节点的直接前驱节点;数据字段: 用于存储数据元素. 指针字段: 用于指向当前节点的直接后继;
图2双向链表的节点结构
因此,双向链表的节点结构以C语言实现为:
typedef struct line{
struct line * prior; //指向直接前趋
int data;
struct line * next; //指向直接后继
}line;
与单链表相比,双链表的创建是每个节点仅具有一个用于指向直接前任的指针字段. 因此,我们可以轻松地基于单链接列表创建一个双链接列表.
应该注意,与单链表不同,在创建双链表的过程中链表c语言,每个创建的新节点都必须与其前任节点建立两个联系,即:
以下是用于创建双向链接列表的C语言实现代码:
line* initLine(line * head){
head=(line*)malloc(sizeof(line));//创建链表第一个结点(首元结点)
head->prior=NULL;
head->next=NULL;
head->data=1;
line * list=head;
for (int i=2; i<=3; i++) {
//创建并初始化一个新结点
line * body=(line*)malloc(sizeof(line));
body->prior=NULL;
body->next=NULL;
body->data=i;
list->next=body;//直接前趋结点的next指针指向新结点
body->prior=list;//新结点指向直接前趋结点
list=list->next;
}
return head;
}
我们可以尝试输出在主函数中创建的双向链表,C语言代码如下:
#include
#include
//节点结构
typedef struct line{
struct line * prior;
int data;
struct line * next;
}line;
//双链表的创建函数
line* initLine(line * head);
//输出双链表的函数
void display(line * head);
int main() {
//创建一个头指针
line * head=NULL;
//调用链表创建函数
head=initLine(head);
//输出创建好的链表
display(head);
//显示双链表的优点
printf("链表中第 4 个节点的直接前驱是:%d",head->next->next->next->prior->data);
return 0;
}
line* initLine(line * head){
//创建一个首元节点,链表的头指针为head
head=(line*)malloc(sizeof(line));
//对节点进行初始化
head->prior=NULL;
head->next=NULL;
head->data=1;
//声明一个指向首元节点的指针,方便后期向链表中添加新创建的节点
line * list=head;
for (int i=2; i<=5; i++) {
//创建新的节点并初始化
line * body=(line*)malloc(sizeof(line));
body->prior=NULL;
body->next=NULL;
body->data=i;
//新节点与链表最后一个节点建立关系
list->next=body;
body->prior=list;
//list永远指向链表中最后一个节点
list=list->next;
}
//返回新创建的链表
return head;
}
void display(line * head){
line * temp=head;
while (temp) {
//如果该节点无后继节点,说明此节点是链表的最后一个节点
if (temp->next==NULL) {
printf("%d\n",temp->data);
}else{
printf("%d ",temp->data);
}
temp=temp->next;
}
}
运行程序的结果:
1 2 3 4 5
链接列表中第四个节点的直接前驱是: 3
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-167988-1.html