Data Structure and Algorithm - Detailed Explanation of Doubly Linked List and Creation (C Language)

The linked list we have learned so far, whether it is a dynamic linked list or a static linked list, each node in the table contains only one pointer (cursor), and they all point to the direct successor node uniformly. This kind of linked list is usually called a one-way linked list (or single linked list) .

Although the use of singly linked list can 100% solve the storage problem of "one-to-one" data logical relationship, but when solving some special problems, singly linked list is not the most efficient storage structure. For example, if the algorithm needs to find a large number of predecessor nodes of a specified node, using a singly linked list is undoubtedly disastrous, because a singly linked list is more suitable for "from front to back" search, and "from back to front" search and Not its forte.

In order to efficiently solve similar problems, let's learn about doubly linked lists (referred to as double linked lists) .

Understand the doubly linked list from the name, that is, the linked list is "two-way", as shown in the following figure:

Schematic diagram of doubly linked list structure

Bidirectional means that the logical relationship between nodes is bidirectional, but usually only one head pointer is set, unless the actual situation requires it.

As can be seen from the figure above, each node in the doubly linked list contains the following three parts of information (as shown in the figure below):

  1. Pointer field: used to point to the direct predecessor node of the current node;
  2. Data field: used to store data elements.
  3. Pointer field: used to point to the immediate successor node of the current node;

Node composition of doubly linked list

Therefore, the node structure of the doubly linked list is implemented in C language as:

typedef struct line{
    struct line * prior; //指向直接前趋
    int data;
    struct line * next; //指向直接后继
}line;

Creation of doubly linked list

Compared with the single-linked list, the double-linked list only has one more pointer field for each node to point to the direct predecessor. Therefore, we can easily create a double-linked list on the basis of a single-linked list.

It should be noted that, unlike the single-linked list, in the process of creating a double-linked list, every time a new node is created, two connections must be established with its predecessor node, namely:

  • Point the prior pointer of the new node to the direct predecessor node;
  • Point the next pointer of the direct predecessor node to the new node;

Here is the C language implementation code for creating a doubly linked list:

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;
}

We can try to output the created double linked list in the main function, the C language code is as follows:

#include <stdio.h>
#include <stdlib.h>
//节点结构
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;
    }
}

Program running result:

1 <-> 2 <-> 3 <-> 4 <-> 5
链表中第 4 个节点的直接前驱是:3

2023 new version of data structure and algorithm Java video tutorial (Part 1), data structure and algorithm that senior java programmers must learn
2023 new version of data structure and algorithm Java video tutorial (part 2), data structure and algorithm that java senior programmer must learn

Guess you like

Origin blog.csdn.net/Itmastergo/article/details/131822505