# 1. Summary

This paper mainly introduces the concept of two-way circular linked list and its code implementation in C language.

# 2. Introduction of two-way circular linked list

In the previous section, we introduced the one-way headless acyclic linked list, but let's think about it carefully. Since the linked list is one-way, one of the direct consequences is that we can only find the next node through the previous node, not the previous node through the latter node.

Why? Very simple, because the node only has a pointer field that identifies the address of the successor node.

So what if we want to find the previous node of a node directly? It is also very simple. Just add a pointer field to the node and record the address of the precursor.

```typedef struct DLList
{
struct DLList* next; //Pointer to record the address of the successor node
struct DLList* prev; //Pointer that records the address of the precursor node
DLListDataType data; //Data domain
}DLList;
```

In addition, in a one-way headless acyclic list, we store NULL in the pointer field of the last node, indicating that there are no nodes behind it. Therefore, the linked list is acyclic.

So what if it's a circular linked list? Smart, you must have thought that as long as the next pointer field of the tail node stores the address of the head node, the whole linked list will form a perfect closed loop!

Yes, like this, I wonder if you have seen such a picture in physics class. This is a closed loop!

## 2.3. Two way circular linked list

OK, OK, let's not stray from the topic. Now that we have introduced what is a two-way linked list and what is a circular linked list, let's combine these two properties and take a look at the true face of Lushan, which takes the lead in the two-way circular linked list:

The linked list contains a head node. Each node has a data field and two pointer fields next and prev. The data field of the head node does not store valid data

# 3. Code implementation

```#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int DLListDataType;

typedef struct DLList
{
struct DLList* next;
struct DLList* prev;
DLListDataType data;
}DLList;

DLList* DLListInit();
void DLListInsert(DLList* pos, DLListDataType x);
void DLListErase(DLList* pos);
```

## 3.2. Interface documents

Here, we need to realize the functions of initialization, addition, deletion, query and modification, printing, calculating the number of nodes and empty judgment of the linked list.

It is worth noting that the operations of header insertion, tail insertion, header deletion and tail deletion can reuse the interfaces inserted and deleted at any position.

```#define _CRT_SECURE_NO_WARNINGS 1
#include "DLList.h"
{
DLList* ret = (DLList*)malloc(sizeof(DLList));
if (ret == NULL)
{
return NULL;
}
ret->data = x;
ret->next = NULL;
ret->prev = NULL;

return ret;
}
DLList* DLListInit()
{
{
printf("Init Fail!\n");
return NULL;
}
}
{
{
DLList* tmp = cur;
cur = cur->next;
free(tmp);
tmp = NULL;
}
}
{
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
cur = NULL;
}
{
if (newnode == NULL)
{
printf("pushback fail\n");
exit(-1);
}
}
{
if (newnode == NULL)
{
printf("push front fai\n");
exit(-1);
}
}
{

//{
//	return;
//}
return;

}
{

{
return;
}

return;

}
DLList* DLListFind(const DLList* phead, DLListDataType x)
{
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
void DLListInsert(DLList* pos , DLListDataType x) // insert before
{
assert(pos);
if (newnode == NULL)
{
printf("newnode create failded\n");
exit(-1);
}
newnode->next = pos;
newnode->prev = pos->prev;
pos->prev->next = newnode;
pos->prev = newnode;
}
void DLListErase(DLList* pos)
{
assert(pos);
pos->prev->next = pos->next;
pos->next->prev = pos->prev;
free(pos);
pos = NULL;
}

{
size_t count = 0;
{
++count;
cur = cur->prev;
}
return count;
}

{
}
```

## 3.3. Test documents

```#include "DLList.h"

void Test1()
{
DLList* plist = DLListInit();

printf("empty = %d\n", DLListEmpty(plist));

DLListPushBack(plist, 1);
DLListPrint(plist);
printf("empty = %d\n", DLListEmpty(plist));

DLListPushBack(plist, 2);
DLListPrint(plist);

DLListPushFront(plist, 3);
DLListPrint(plist);

DLListPushFront(plist, 4);
DLListPrint(plist);

DLListPopFront(plist);
DLListPrint(plist);

printf("count = %d\n", DLListSize(plist));

if (DLListFind(plist, 3))
{
DLListInsert(DLListFind(plist, 3), 9);
}
if (DLListFind(plist, 2))
{

DLListInsert(DLListFind(plist, 2), 9);
}
DLListPrint(plist);
DLListPopBack(plist);
DLListPopBack(plist);

DLListPopBack(plist);

DLListPopBack(plist);
DLListPrint(plist);

DLListPopBack(plist);
DLListPrint(plist);

DLListPrint(plist);
DLListPopBack(plist);

DLListPopBack(plist);
DLListPopBack(plist);

DLListPopBack(plist);
DLListPrint(plist);

DLListPrint(plist);
DLListDestroy(plist);
return 0;
}
int main()
{
Test1();

}
```

# 4. References

1. Dahua data structure p81

Posted by Svoboda on Sat, 20 Nov 2021 19:58:03 -0800