Plant Wars Leads Doubly Circular Linked List - Pure C

"Flowers float and water flows, a kind of lovesickness, and two worries."
"There is no way to eliminate this feeling, so I raised my brows, but it came to my heart."

foreword

insert image description here
These two linked lists are the most commonly used in real life. A headless one-way acyclic linked list. and a headed doubly linked list.
Headless one-way acyclic linked list : The structure is simple, and it is generally not used to store data alone. In practice, it is more of a substructure of other data structures , such as hash buckets, graph adjacency lists, and so on. In addition, this structure appears a lot in the written test interview . Headed doubly circular linked list : The structure is the most complex and is generally used to store data separately. The linked list data structures used in practice are all leading doubly circular linked lists. In addition, although the structure of this structure is complex, it will be found that the structure will bring many advantages after using the code to implement it, but the implementation is simple, and we will know it after the code is implemented.

1. Create the structure

Note: the typedef works on line 7. So 5 and 6 also need to write the struct ListNode type.

typedef int LNDataType;

typedef struct ListNode
{
    
    
	  struct ListNode* prev;
 	  struct ListNode* next;
      LNDataType val;
}LN;

2. malloc new node

Note: It is necessary to judge whether the newly opened node is empty.

//申请一个新节点
LN* BuynewNode(LNDataType x)
{
    
    
	LN* newNode = (LN*)malloc(sizeof(LN));
	if (newNode == NULL)
	{
    
    
		printf("malloc fail");
		exit(-1);
	}
	newNode->next = NULL;
	newNode->prev = NULL;
	newNode->val = x;
	return newNode;
}

3. Create a sentinel node

Note : Because the content of the plist pointer needs to be changed, that is, the point of the plist pointer needs to be changed, so the address of the plist needs to be passed.

One sentence is: whose content needs to be changed, the address of whomever needs to be changed .

Here is a very ingenious and very clever point, that is, the successor and predecessor of phead are pointing to themselves (phead), here is the sentinel bit node imitating the C++ STL library.

I can only admire the great god who came up with these things. If the sentinel node is designed in this way, the subsequent tail insertion and tail deletion are particularly ingenious.
insert image description hereinsert image description here

test.c

	LN* plist = NULL;
	ListNodeInit(&plist);

List.h

//初始化节点
void ListNodeInit(LN** pphead)
{
    
    
	LN* newNode = BuynewNode(0);
	*pphead = newNode;
	(*pphead)->next = *pphead;
	(*pphead)->prev = *pphead;
}

4. Tail plug

Note: The reason for the assertion is because, even if the linked list does not have a node, the linked list has at least one head, so the phead must not be empty.

The reason why the address is not passed here is because you don't need to change the point of plist, what you change is the value in the structure pointed to by plist.

The situation of multiple node tail insertion is shown in the figure.
insert image description here
The tail of a node.insert image description here

//尾插
void ListNodePushBack(LN* phead, LNDataType x)
{
    
    
	assert(phead);
	LN* newNode = BuynewNode(x);
	LN* tail = phead->prev;
	tail->next = newNode;
	newNode->prev = tail;
	newNode->next = phead;
	phead->prev = newNode;
}

5. Print

Note: Because of the head, cur starts from the second position.

//打印
void ListNodePrint(LN* phead)
{
    
    
	LN* cur = phead->next;
	while (cur != phead)
	{
    
    
		printf("%d ", cur->val);
		cur = cur->next;
	}
	printf("\n");
}

6. Tail deletion

Note that the head node cannot be deleted. Freeing the head node will cause a wild pointer, and it will cause illegal access when it is accessed again.
So use assert to assert that it is not the first node.

//尾删
void ListNodePopBack(LN* phead)
{
    
    
	assert(phead);
	assert(phead->next != phead);
	LN* tail = phead->prev;
	LN* tailPrev = tail->prev;
	free(tail);
	tail = NULL;
	phead->prev = tailPrev;
	tailPrev->next = phead;
}

7. Header

It is best to use next to record the next node. It's convenient and clear

//头插
void ListNodePushFront(LN* phead, LNDataType x)
{
    
    
	assert(phead);
	LN* newNode = BuynewNode(x);
	LN* next = phead->next;
	phead->next = newNode;
	newNode->prev = phead;
	newNode->next = next;
	next->prev = newNode;
}

8. Insert before the specified position pos

In general, when there is
insert image description hereonly one node.
insert image description here
The following code works in both cases.

//指定位置前插入,极限是头插
void ListNodeInsert(LN* pos, LNDataType x)
{
    
    
	if (pos == NULL)
	{
    
    
		printf("没有找到这个数\n");
		return;
	}
	LN* newNode = BuynewNode(x);
	LN* tailPrev = pos->prev;
	tailPrev->next = newNode;
	newNode->prev = tailPrev;
	newNode->next = pos;
	pos->prev = newNode;
}

9. Delete the pos node at the specified location

Normal case
insert image description here
Limit tail deletion
insert image description here
The following code applies to both cases.

//指定位置删除
void ListNodeErease(LN* phead, LN* pos)
{
    
    
	if (pos == phead || pos == NULL)
	{
    
    
		printf("pos指向头,或为空\n");
		return;
	}
	LN* posPrev = pos->prev;
	LN* posNext = pos->next;
	posPrev->next = posNext;
	posNext->prev = posPrev;
	free(pos);
	pos = NULL;
}

10. Destroy the linked list

Note: This is equivalent to free after malloc is used up. Otherwise, memory leaks will occur.
cur can be left empty, but it is of little use, because cur is a formal parameter, a formal parameter is a temporary copy of the actual parameter, and the actual parameter cannot be changed by leaving the formal parameter empty. External arguments can still illegally access the space pointed to by cur.

//链表销毁
void ListNodeDestroy(LN* phead)
{
    
    
	assert(phead);
	LN* cur = phead->next;
	LN* next = cur->next;
	while (cur != phead)
	{
    
    
		next = cur->next;
		free(cur);
		cur = NULL;
		cur = next;
	}
	free(phead);
	phead = NULL;
}

Guess you like

Origin blog.csdn.net/qq2466200050/article/details/123664698