content
2. Implementation of a singly linked list
Implementation of the function
(12) Remember to destroy when you are finished using it
Preface: The singly linked list is the basis of the double linked list and the circular linked list to be learned later. If we want to continue to understand the data structure and C++ in depth, we must lay the foundation stone! Come and learn with me next!
Here we will simply implement the addition and deletion of the singly linked list.
1. Singly linked list
Concept: Linked list is a non-consecutive and non-sequential storage structure in physical storage structure. The logical order of data elements is realized through the link order of pointers in the linked list.
(The closest thing a linked list is to our lives is a train.)
2. Implementation of a singly linked list
Next, we will implement the addition, deletion and modification of the singly linked list.
head File
#pragma once #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int SLDataType; //链表的创建 typedef struct SListNode { SLDataType data;//val struct SListNode* next;//存储下一个结点的地址 }SListNode,SLN; //打印链表 void SListPrint(SListNode* phead); //尾插 void SListPushBack(SListNode** pphead, SLDataType x); //头插 void SListPushFront(SListNode** pphead, SLDataType x); //尾删 void SListPopBack(SListNode** pphead); //头删 void SListPopFront(SListNode** pphead); //查找 SListNode* SListFind(SListNode* phead, SLDataType x); //在pos位置之前插入 void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x); //删除pos位置 void SListErase(SListNode** pphead, SListNode* pos); //在pos位置之后插入 void SlistInserAfter(SListNode* pos, SLDataType x); //删除pos后的值 void SlistEraseAfter(SListNode* pos); //用完销毁 void SListDestroy(SListNode** pphead);
Implementation of the function
(1) Print the linked list
void SListPrint(SListNode* phead) { assert(phead); SListNode* cur = phead; if (cur == NULL) { printf("SList is NULL\n"); } while (cur != NULL) { printf("%d->", cur->data); cur = cur->next; } printf("NULL\n"); }
(2) Dynamic application node
Apply a data x dynamically to the node.
SListNode* BuySList(SLDataType x) { SListNode* newnode = (SListNode*)malloc(sizeof(SListNode)); if (newnode == NULL) { printf("malloc fail\n"); exit(-1); } else { newnode->data = x; newnode->next = NULL; } return newnode; }
(3) Tail plug
void SListPushBack(SListNode** pphead, SLDataType x) { assert(pphead); SListNode* newnode = BuySList(x); if (*pphead == NULL) { *pphead = newnode; } else { //找尾 SListNode* tail = *pphead; while (tail->next != NULL) { tail = tail->next; } //走完循环找到尾 tail->next = newnode; } }
(4) Head plug
void SListPushFront(SListNode** pphead, SLDataType x) { assert(pphead); SListNode* newnode = BuySList(x); newnode->next = *pphead; *pphead = newnode; }
(5) Tail deletion
void SListPopBack(SListNode** pphead) { assert(pphead); //当链表只有一个结点时 if (*pphead == NULL) { printf("SListNode is NULL\n"); return; } //当链表只有一个结点时 else if ((*pphead)->next == NULL) { free(*pphead); *pphead = NULL; } //当链表有多个结点时 else { SListNode* tail = *pphead; while (tail->next->next != NULL) { tail = tail->next; } free(tail->next); tail->next = NULL; } }
(6) Header deletion
void SListPopFront(SListNode** pphead) { assert(pphead); if (*pphead == NULL) { printf("SList is NULL\n"); return; } else { SListNode* next = (*pphead)->next; free(*pphead); *pphead = next; } }
(7) Find
SListNode* SListFind(SListNode* phead, SLDataType x) { assert(phead); SListNode* cur = phead; while (cur != NULL) { if (cur->data == x) { return cur; } //如果没找到就往下走 cur = cur->next; } //循环完成后还没找到就说明链表中没有该值 return NULL; }
(8) Insert before pos
void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x) { assert(pphead); assert(pos); //pos是第一个位置 if (pos == *pphead) { SListPushFront(pphead, x); } //pos不是第一个位置 else { SListNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } SListNode* newnode = BuySList(x); prev->next = newnode; newnode->next = pos; } }
(9) delete pos
void SListErase(SListNode** pphead, SListNode* pos) { assert(pphead); assert(pos); //1、头结点为空 if (*pphead == NULL) { printf("SList is NULL\n"); return; } //2、删除第一个结点 else if (pos == *pphead) { SListPopFront(pphead); } //3、其他结点 else { SListNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } prev->next = pos->next; free(pos); pos = NULL; } }
(10) Insert after pos
Compared with inserting before pos, inserting after pos can be used without a header node, no matter where pos is located.
void SListInsertAfter(SListNode* pos, SLDataType x) { assert(pos); SListNode* newnode = BuySList(x); SListNode* next = pos->next; pos->next = newnode; newnode->next = next; //下面这种方式也可以 /*SListNode* newnode = BuySList(x); newnode->next = pos->next; pos->next = newnode;*/ }
(11) Delete after pos
void SListEraseAfter(SListNode* pos) { assert(pos); SListNode* next = pos->next; if (next) { pos->next = next->next; free(next); next = NULL; } }
(12) Remember to destroy when you are finished using it
void SListDestroy(SListNode** pphead) { assert(pphead); SListNode* cur = *pphead; while (cur) { SListNode* next = cur->next; free(cur); cur = next; } *pphead = NULL; }
3. Test of each function
#include "SList.h" void test1() { SListNode* slist = NULL; //测试尾插 SListPushBack(&slist, 1); SListPushBack(&slist, 2); SListPushBack(&slist, 3); SListPushFront(&slist, 5); SListPushFront(&slist, 4); SListPrint(slist); //测试头插 SListPushFront(&slist, 5); SListPushFront(&slist, 4); SListPrint(slist); //测试尾删 SListPopBack(&slist); SListPopBack(&slist); SListPrint(slist); //测试头删 SListPopFront(&slist); SListPopFront(&slist); SListPopFront(&slist); SListPrint(slist); //测试查找 SListNode* ret1 = SListFind(slist, 5); printf("%d\n", ret1->data); /*SListNode* ret2 = SListFind(slist, 2); printf("%d\n", ret2->data);*/ //pos前插测试 SListNode* pos = SListFind(slist, 1); if (pos) { SListInsert(&slist,pos,3); } SListPrint(slist); pos = SListFind(slist, 1); if (pos) { SListInsert(&slist, pos, 10); } SListPrint(slist); //删除pos测试 pos = SListFind(slist, 10); if (pos) { SListErase(&slist, pos); } SListPrint(slist); //测试在pos后插入 pos = SListFind(slist, 3); if (pos) { SListInsertAfter(pos, 6); } SListPrint(slist); pos = SListFind(slist, 1); if (pos) { SListInsertAfter(pos, 8); } SListPrint(slist); //测试删除pos后的值 pos = SListFind(slist, 1); if (pos) { SListEraseAfter(pos); } SListPrint(slist); } int main() { test1(); return 0; }
operation result:
This is the end of the implementation of the singly linked list. If you want to go further, please pay attention to the follow-up----single linked list OJ, so that you will no longer be confused!