1.之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”。如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链表,增加算法的时间复杂度,影响整体效率。为了快速便捷地解决这类问题,在单向链表的基础上,给各个结点额外配备一个指针变量,用于指向每个结点的直接前趋元素。这样的链表被称为“双向链表”或者“双链表”。
2.
并且实现(1,2,3)中插入一个结点 4,变成(1,4,2,3)操作:
代码:
#include<stdio.h>
#include<stdlib.h>
//结构体定义
typedef struct line {
struct line *prior;//指向直接前驱
int data;
struct line *next;//指向直接后驱
}line;
//结构体初始化
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;
}
//在双向链表中插入数据4,,变成(1,4,2,3)
line *insertLine(line *head, int data, int add) {
//新建数据域为data的结点
line *temp = (line *)malloc(sizeof(line));
temp->prior = NULL;
temp->next = NULL;
temp->data = data;
//插入链表头,要特殊考虑
if (add == 1) {
temp->next = head;
head->prior = temp;
head = temp;
}
else
{
line *body = head;
//找到要插入位置的前一个结点
for (int i = 1; i < add - 1; i++) {
body = body->next;
}
//判断条件为真,说明插入位置为链表尾
if (body->next == NULL) {
body->next = temp;
temp->prior = body;
}
else
{
body->next->prior = temp;
temp->next = body->next;
body->next = temp;
temp->prior = body;
}
}
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;
}
}
int main() {
line *head = NULL;
head = initLine(head);
head = insertLine(head, 4, 2);
display(head);
return 0;
}