Time：2021-9-6

# 0. To the point

article[linked list of data structure] after reading this article, I finally understand the linked listThe chain storage structure has been introduced, and the most basic (simple) implementation of the chain storage structure – one-way linked list has been introduced.

One way linked list, as the name suggests, is one-way.

Because each node of the single linked list has only one data field and one pointer field, and the pointer field only stores the address of the next node, we can only find its direct successor node through a node, but we can’t find its direct predecessor node through a node.

In addition, since the single linked list ends at the tail node (the last node of the linked list), the pointer field of the tail node is`NULL`, to represent the termination of the linked list, which leads us to traverse to the tail node. If we want to traverse again, we can only manually return to the head node and start traversal.

In order to make up for the above two shortcomings of a single linked list, the following introduces two kinds of linked lists. They are all deformations of a single linked list. If you understand a single linked list, you will easily understand these two deformations. # 1. One way circular linked list

## 1.1. Structure

The pointer field of the tail node of a single linked list is`NULL`, so the single linked list ends here. If we use the pointer field of the tail node of the single linked list to store the address of the head node, that is, the direct successor node of the tail node is the head node. In this way, the single linked list forms a ring (cycle), which is called single cycle linked list. ## 1.2. Implementation ideas

The one-way circular linked list evolved from the single linked list and is regarded as the “son” of the single linked list. Therefore, the structure of the single linked list is fully applicable to the one-way circular linked list. You can also see from the above figure that the structure has not changed greatly. The difference between the two is only in the tail node, so we only need to work on the tail node and the operations related to the tail node.

Therefore, the structure of one-way circular linked list is the same as that of single linked list.

``````/*The structure of the node of a one-way circular linked list*/
typedef struct _Node {
int data; // Data fields: storing data
struct _ Node *next; // Pointer field: stores the address of the direct successor node
} Node;``````

In order to unify the operation of empty linked list and non empty linked list, we use the linked list of the leading node to realize it.

## 1.3. Empty linked list and initialization

An empty linked list, as shown in the figure, has only one header pointer and header node: The pointer field of the head node points to itself to form a loop, which we can use to judge whether the linked list is empty.

``````if (head->next == head) {
}``````

Want to initialize an empty linked list is very simple, create the head node, make the head node`next`The pointer points to itself:

``````Node *create_node(int elem)
{
Node *new = (Node *) malloc(sizeof(Node));
new->data = elem;
new->next = NULL;
return new;
}

/**
*/
{
//The next pointer of the head node points to itself to form a ring
}``````

## 1.4. Insertion operation

Only head interpolation and tail interpolation are demonstrated here

Because of the leading node, you do not need to consider whether it is an empty linked list. The following figure shows the process of inserting two elements into the head of an empty linked list: ``````/**
*The new node is the direct successor of the head node
*Elem: data of new node
*/
{
Node *new = create_node(elem);
//After the new node is inserted into the head node
}``````

[tail interpolation]

In order to be as simple as possible, we do not set the tail pointer to the tail node. Therefore, before tail insertion, we need to traverse to the tail node with the help of a pointer, and then insert.

``````/**
*Tail insertion method: the newly inserted node is always at the end of the linked list
*Elem: data of new node
*/
{
Node *new = create_node(elem);
Node *tail = head_ node; // The tail pointer points to the header node
while (tail->next !=  head_ Node) {// tail traverses to the end of the linked list
tail = tail->next;
}
//Tail insertion
new->next = tail->next;
tail->next = new;
}``````

## 1.5. Delete

The essence of deletion is to “skip” the node to be deleted, so we need to find the direct precursor node of the node to be deleted, and then make it the direct precursor node`next`The pointer points to its direct successor node to “skip” the node to be deleted. Finally, save its data field and release the node to complete the deletion.

Only header deletion is demonstrated here.

Because the deleted node is the direct successor node of the head node, we don’t have to look for the direct precursor node of the node to be deleted. ``````/**
*Elem: pointer to save data variable
*/
{
Printf ("empty linked list, no element can be deleted\ n");
return;
}
Node *first_ node = head_ node->next; // First node: the next node of the first node
*elem = first_ node->data; // Save the data of the deleted node
head_ node->next = first_ node->next; // Delete Vertex
free(first_ node); // release
}``````

## 1.6. Traversal operation

We can cycle through the linked list again and again. The following is the code for cyclic printing of nodes 20 times:

``````/**
*Cycle printing 20 nodes
*/
{
return;
}
for (int i = 0; i <= 20; i++) {
printf("%d ", p->data);
}
p = p->next;
}
printf("\n");
}``````

# 2. Two way linked list

## 2.1. Structure

As the name suggests, a two-way linked list has two directions, one pointing forward and the other pointing back. In this way, we make up for the defect that a node of the single linked list can only find its direct successor. As shown in the figure: ## 2.2. Implementation ideas

In order to achieve the effects before and after the signifier, only`next`Pointers are definitely not enough, so we need to add another pointer——`prev`, the pointer points to the direct precursor node of a node.

``````/*Node structure of bidirectional linked list*/
typedef struct _Node {
int data; // Data domain
struct _ Node *prev; // Pointer to the direct precursor node
struct _ Node *next; // Pointer to direct successor node
} Node;``````

## 2.3. Empty linked list and initialization

The empty linked list of the two-way linked list is shown in the figure: To initialize such an empty linked list, you need to create a header node, and then empty the two pointer fields:

``````Node *create_node(int elem)
{
Node *new = (Node *)malloc(sizeof(Node));
new->data = elem;
new->prev = NULL;
new->next = NULL;
return new;
}

{
}``````

## 2.4. Insertion operation

Only the head insertion method is demonstrated here. The process is as follows:  The code is as follows:

``````/**
*The new node is the direct successor of the head node
*Elem: data of new node
*/
{
Node *new = create_node(elem);
Node *first_ node = head_ node->next; // First node: the next node of the first node
//The prev pointer of the first node points to the new node
first_node->prev = new;
//The next pointer of the new node points to the first node
new->next = first_node;
}
//The prev pointer of the new node points to the header node
//The next pointer of the header node points to the new node
}``````

## 2.5. Delete

Only header deletion is demonstrated here. The following figure shows the process of deleting a two-way linked list header with two element nodes into an empty linked list: The code is as follows:

``````/**
*Elem: pointer to save variable
*/
{
Node *first_ node = head_ node->next; // First node to be deleted: the next node of the head node
if (head_ Node - > next = = null) {// null
Printf ("empty linked list, no element can be deleted\ n");
return;
}
*elem = first_ node->data; // Save data

if (first_node->next != NULL) {
first_node->next->prev = first_node->prev;
}
first_node->prev->next = first_node->next;
free(first_node);
}``````

## 2.6. Traversal operation

Yes`next`Pointer field, we can traverse backward all the way; Yes`prev`Pointer field, we can traverse all the way forward.

The code is no longer shown here.

# 3. Summary

Knowing the one-way circular linked list and two-way linked list is like taking building blocks. We can also create a two-way circular linked list. There is no more demonstration here. Readers can try it by themselves. As long as you understand the above three linked lists, it is not difficult.

The above is part of the tricks of the linked list, which will continue to be updated in the future.

Complete code, please move toGitHub | Giteeobtain. 