## Circular linked list

Last time I talked about this single linked list, the linked list has great advantages, but its disadvantages are also obvious. I mean, it can only go from one node to the next node, but can't access the previous node. The circular linked list can solve this problem. Of course, it's more convenient to use a two-way linked list

Sometimes when solving specific problems, we need to make a slight adjustment to its structure. For example, you can connect the two ends of a linked list to make it a circular linked list, which is usually called a circular linked list.

I mean, this is the same as the meaning of its name. Just point the pointer of the last node in the list to the head node, and the linked list can form a ring. It's still relatively simple. It should be noted that although the circular linked list is circular, it is essentially a linked list,

It should be noted that although the circular linked list is a ring, it is still a linked list in essence. Therefore, in the circular linked list, you can still find the head pointer and the first element node. The only difference between a circular linked list and an ordinary linked list is that the circular linked list is connected end to end, and everything else is exactly the same.

Let's see how we got this circular linked list

1. Set the tail pointer of the circular linked list. Because the tail pointer will change constantly during the operation of the linked list, the pointer to the head pointer is set in the formal parameters of some functions. And the end judgment condition of the linked list becomes whether q is equal to the tail pointer.

2. Note that the passed arguments need to be addressed

3. The advantages of circular linked list lie in the combination of double linked lists and the simplicity of tail insertion (first create a new node to point to the head node, and then point the next field of the tail pointer to the new node)

4. When creating a linked list, the tail insertion method is used instead of the head insertion method (because the head insertion method is difficult to update the tail pointer, so the last tail pointer needs to be updated again). The head insertion method is directly used to establish the head pointer rather than the tail pointer

Let's post a code now? Hey, we're coming

#include<stdio.h> #include<stdlib.h> typedef struct Node { int data; struct Node * next; }Node, *LinkList; LinkList Creat(); void Destroy(LinkList *L); void Insert(LinkList *L, int val, int index); void Delete(LinkList *L, int index); void Traverse(LinkList L); int main() { LinkList L = Creat(); Traverse(L); Insert(&L, 1, 5); printf("After inserting is :\n"); Traverse(L); printf("After deleting is :\n"); Delete(&L, 2); Traverse(L); Destroy(&L); Traverse(L); } LinkList Creat() { LinkList L = (LinkList)malloc(sizeof(Node));//Use the L pointer to point to the new node, where l is not the tail pointer int n; L->data = -1; L->next = L;//The pointer field of the head node points to the head node. Attention! Here is the initialization of the tail pointer. printf("Please enter the number you want input:(>5)"); scanf_s("%d", &n); printf("input the number:\n"); for (int i = 0; i < n; i++) { LinkList p = (LinkList)malloc(sizeof(Node)); scanf_s("%d", &p->data); p->next = L->next; L->next = p; L = p; } return L;//Returns a pointer to the tail node } void Destroy(LinkList *L) { LinkList q = (*L)->next->next; LinkList p; (*L) = (*L)->next; while (q != (*L)) { p = q->next; free(q); q = p; } (*L)->next = (*L); } void Insert(LinkList *L, int val, int index) { LinkList p = (LinkList)malloc(sizeof(Node)); p->data = val; LinkList q = (*L)->next; for (int i = 1; q != (*L) && i < index; i++) q = q->next; p->next = q->next; q->next = p; if (p == (*L)) (*L) = p; } void Delete(LinkList *L, int index) { LinkList q = (*L)->next, p; for (int i = 0; i < index; i++) q = q->next; p = q->next; q->next = p->next; free(p); } void Traverse(LinkList L) { LinkList q = L->next->next;//This is the initial node while (q != L) { printf("%d->", q->data); q = q->next; } printf("NULL\n");

We have also added, deleted, modified, checked and reversed our. In fact, this part is similar to the operation of one-way linked list. [LeetCode force button brush question | sword finger Offer 24. Reverse linked list - BiliBili] https://b23.tv/myXqF2V

I also saw a video of reversing the linked list. Although it is not c language, the principle is the same, which is harmless.

## Bidirectional linked list

There are so many things about circular linked list. Next, let's talk about the two-way linked list we didn't finish talking about last time.

In fact, this is also very simple. The one-way linked list stores a pointer to the next node. Let's analogy. We all save next. Why don't we save a prior

#include <stdio.h> #include <stdlib.h> typedef struct line{ struct line * prior; int data; struct line * next; }line;

To facilitate our future use? Right.

### Add node to bidirectional linked list

According to the position where the data is added to the bidirectional linked list, it can be divided into the following three cases:

Add to header

To add a new data element to the header, you only need to establish a double-layer logical relationship between the element and the header element.

In other words, assuming that the new element node is temp and the header node is head, you need to do the following two steps:

temp->next=head; head->prior=temp;

Move the head to temp and point to the new header again;

### Add to middle of table

Similar to adding data to a single linked list, adding data to the middle of a two-way linked list requires the following two steps.

The new node first establishes a two-level logical relationship with its direct successor nodes; The direct precursor node of the new node establishes a two-level logical relationship with it; Add data elements in the middle of the bidirectional linked list

Adding data elements in the middle of a two-way linked list to the footer is the same as adding data elements to the header,

Find the last node in the double linked list; Make the new node and the last node have a double-layer logical relationship; Add data elements at the end of a two-way linked list

I also found some pictures for you to understand

line * insertLine(line * head,int data,int add){ //Create a new node whose data field is data line * temp=(line*)malloc(sizeof(line)); temp->data=data; temp->prior=NULL; temp->next=NULL; //Special consideration shall be given to inserting into the chain header if (add==1) { temp->next=head; head->prior=temp; head=temp; }else{ line * body=head; //Find the previous node where you want to insert for (int i=1; i<add-1; i++) { body=body->next; } //If the judgment condition is true, it indicates that the insertion position is the end of the linked list 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; }

Let's talk about the linked list this time. What else? Let's talk about it next time. Bye.