1. The concept of singly linked list
Concept: Linked list is a non-continuous and non-sequential storage structure in physical storage structure , but linked list is logically continuous and sequential, and the logical order of data elements is realized through the order of pointer connection in the linked list.
1.2 Structure of linked list
Let's redefine a new type called SLDataType for int. Here we want to explain that if we want to change the data type, we can change it directly here, without changing them one by one in the program.
Here, SLTDataType data is used to store data, and *next is essentially a pointer, which actually stores the address of the next data , and is also the main part of the "bridge" in the single linked list
We actually store it like this, the address of the next memory is stored in a memory block
2. Implementation of singly linked list
Let's give everyone the declaration of the function first.
#pragma once
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
void SLTPrint(SLTNode* phead);//打印单链表i
void SLPushFront(SLTNode** pphead, SLTDataType x);//头插
void SLPushBack(SLTNode** pphead, SLTDataType x);//尾插
void SLPopFront(SLTNode** pphead);//头删
void SLPopBack(SLTNode** pphead);//尾删
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//在pos位置之前插入
void SLInsertAfter(SLTNode* pos, SLTDataType x);//在pos后面插入
void SLErase(SLTNode** pphead, SLTNode* pos);//单链表结点删除
void SLEraseAfter(SLTNode* pos);//结点后面删除
2.1 Memory development
Here I think there is no need to say more, directly apply for space in the memory to open up a memory block
SLTNode* BuyLTNode(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
2.2 tail plug
When we perform tail insertion, there are two situations. The first situation is that what you pass is a null pointer, then we need to open up a space for the plist in pphead to store the address of this space.
The second case: If the passed here is not a null pointer, then we have to create a tail (let tail replace pphead to go one by one), play the role of link, and then let the newly opened memory address be stored in the tail behind, let tail point to the next node until it ends when it is NULL
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
//申请内存
SLTNode* newnode = BuyLTNode(x);
//第一个情况
if (*pphead == NULL)
{
*pphead = newnode;
}
//第二个情况
else
{
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
2.3 head plug
The way we want to implement head insertion is the opposite of tail insertion, that is, let the address of pphead be assigned to the space next to our newly created memory block, so that we have realized a process of finding the old memory from the new memory, and then we will transfer the new memory to the old memory. The address is assigned to our pphead to make the pointer point to the address of the new memory block, thus forming a loop of head insertion
void SLPushFront(SLTNode** pphead, SLTDataType x)
{
SLTNode* newnode = BuyLTNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
2.4 tail deletion
Here is the same as before, what is the core idea? The core idea is to make the pointer to the last memory block NULL and release the last memory block.
void SLPopBack(SLTNode** pphead)
{
assert(*pphead);
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode* tail = *pphead;
while (tail->next->next)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
2.5 head delete
void SLPopFront(SLTNode** pphead)
{
assert(pphead);
SLTNode* del = *pphead;
*pphead = (*pphead)->next;
free(del);
}
2.6 Insert in the middle (before pos)
We write a while loop here to first find the position you want to insert. At this time, we create a space so that the pointer in front of the position you want to insert points to your new space, and the tail of this new space points to the address of your original position before. This completes the middle insertion
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead);
assert(pos);
if (*pphead == pos)
{
SLPushFront(pphead, x);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLTNode* newnode = BuyLTNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
2.7 Insert in the middle (after pos)
When we find the position of pos, let the memory address next to it be stored in the address next to the new memory, and then let the address of the new memory be assigned to the position next to pos, so that the middle insertion is completed
void SLInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuyLTNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
2.8 Delete node
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead);
assert(pos);
if (pos == *pphead)
{
SLTPopFront(pphead);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
2.9 Delete the following nodes
void SLEraseAfter(SLTNode* pos)
{
assert(pos);
assert(pos->next);
SLTNode* next = pos->next;
pos->next = next->next;
free(next);
}
2.10 Print singly linked list
void SLTPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
3. Code summary
SList.c
#include "SList.h"
void SLTPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
SLTNode* BuyLTNode(SLTDataType x)
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void SLPushFront(SLTNode** pphead, SLTDataType x)
{
SLTNode* newnode = BuyLTNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
SLTNode* newnode = BuyLTNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
void SLPopFront(SLTNode** pphead)
{
assert(pphead);
SLTNode* del = *pphead;
*pphead = (*pphead)->next;
free(del);
}
void SLPopBack(SLTNode** pphead)
{
assert(*pphead);
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode* tail = *pphead;
while (tail->next->next)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead);
assert(pos);
if (*pphead == pos)
{
SLPushFront(pphead, x);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLTNode* newnode = BuyLTNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
void SLInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuyLTNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead);
assert(pos);
if (pos == *pphead)
{
SLTPopFront(pphead);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
void SLEraseAfter(SLTNode* pos)
{
assert(pos);
assert(pos->next);
SLTNode* next = pos->next;
pos->next = next->next;
free(next);
}
SList.h
#pragma once
#include<string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
void SLTPrint(SLTNode* phead);//打印单链表i
void SLPushFront(SLTNode** pphead, SLTDataType x);//头插
void SLPushBack(SLTNode** pphead, SLTDataType x);//尾插
void SLPopFront(SLTNode** pphead);//头删
void SLPopBack(SLTNode** pphead);//尾删
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);//在pos位置之前插入
void SLInsertAfter(SLTNode* pos, SLTDataType x);//在pos后面插入
void SLErase(SLTNode** pphead, SLTNode* pos);//单链表结点删除
void SLEraseAfter(SLTNode* pos);//结点后面删除
I will not write the content of test.c here
The above is the article sharing of this single-linked list. If you like it, please support it. Thank you for your support.