⭕接口7:头删(SLTPopFront)
🚨要注意头删有三种情况:1.没有结点(空链表)、2.一个结点、3.多个结点
链表为空不能头删,所以要进行assert断言
🥰请看代码与注释👇
//头删 void SLTPopFront(SLTNode** pphead) { //没有结点(空链表) assert(*pphead); //链表为空,不能头删 assert(pphead); //一个结点 if ((*pphead)->next == NULL) { free(*pphead); *pphead = NULL; } //多个结点 else { SLTNode* cur = *pphead; *pphead = cur->next; free(cur); } }
可以有更简洁高效的写法👇
🥰请看代码与注释👇
//头删 void SLTPopFront(SLTNode** pphead) { //没有结点(空链表) assert(*pphead); assert(pphead); //一个结点 //多个结点 SLTNode* cur = *pphead; *pphead = (*pphead)->next; free(cur); }
⭕接口8:尾删(SLTPopBack)
🚨要注意尾删同样有三种情况:1.没有结点(空链表)、2.一个结点、3.多个结点
链表为空不能尾删,所以要进行assert断言
🥰请看代码与注释👇
//尾删 void SLTPopBack(SLTNode** pphead) { //没有结点(空链表) assert(*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; } }
⭕接口9:查找(SLTFind)
通过遍历进行查找,通常与修改结合联系使用
🥰请看代码与注释👇
//查找 SLTNode* SLTFind(SLTNode* phead, SLTDataType x) { assert(phead); SLTNode* cur = phead; while (cur) { if (cur->data == x) { return cur; } else { cur = cur->next; } } return NULL; }
⭕接口10:修改(SLTModify)
🥰请看代码与注释👇
//修改 void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x) { assert(phead); assert(pos); pos->data = x; }
⭕接口11:在pos位置之前插入数据(SLTInsert)
🥰请看代码与注释👇
//在pos位置之前插入数据 void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) { assert(pphead); assert(pos); //防止给的位置为 空 if (*pphead == pos) { SLTPushFront(pphead, x); } else { SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } SLTNode* newnode = BuyLTNode(x); prev->next = newnode; newnode->next = pos; } }
⭕接口12:在pos位置之后插入数据(SLTInsertAfter)
🥰请看代码与注释👇
//在pos位置之后插入数据 void SLTInsertAfter(SLTNode* pos, SLTDataType x) { assert(pos); //防止给的位置为 空 SLTNode* newnode = BuyLTNode(x); newnode->next = pos->next; pos->next = newnode; }
⭕接口13:删除pos位置的值(SLTErase)
🥰请看代码与注释👇
//删除pos位置的值 void SLTErase(SLTNode** pphead, SLTNode* pos) { assert(pphead); assert(pos); //防止给的位置为 空 if (*pphead == pos) { SLTPopFront(pphead); } else { SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } prev->next = pos->next; free(pos); } }
⭕接口14:删除pos位置之后的值(SLTEraseAfter)
🥰请看代码与注释👇
//删除pos位置之后的值 void SLTEraseAfter(SLTNode* pos) { assert(pos); assert(pos->next); SLTNode* next = pos->next; pos->next = next->next; free(next); }
🐸四、完整代码
🥝SList.h
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> //自定义类型 typedef int SLTDataType; //创建单链表 typedef struct SListNode { SLTDataType data; struct SListNode* next; }SLTNode; //打印 void SLTPrint(SLTNode* phead); //释放 void SLTDestroy(SLTNode** pphead); //创建新结点 SLTNode* BuyLTNode(SLTDataType x); //头插 void SLTPushFront(SLTNode** pphead, SLTDataType x); //尾插 void SLTPushBack(SLTNode** pphead, SLTDataType x); //头删 void SLTPopFront(SLTNode** pphead); //尾删 void SLTPopBack(SLTNode** pphead); //查找 SLTNode* SLTFind(SLTNode* phead, SLTDataType x); //修改 void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x); //在pos位置之前插入数据 void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x); //在pos位置之后插入数据 void SLTInsertAfter(SLTNode* pos, SLTDataType x); //删除pos位置的值 void SLTErase(SLTNode** pphead, SLTNode* pos); //删除pos位置之后的值 void SLTEraseAfter(SLTNode* pos);
🥝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"); } //释放 void SLTDestroy(SLTNode** pphead) { assert(pphead); SLTNode* cur = *pphead; while (cur) { SLTNode* next = cur->next; free(cur); cur = next; } *pphead = NULL; } //创建新结点 SLTNode* BuyLTNode(SLTDataType x) { SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); if (newnode == NULL) { perror("mallic fail"); return; } newnode->data = x; newnode->next = NULL; return newnode; } //头插 void SLTPushFront(SLTNode** pphead, SLTDataType x) { assert(pphead); //链表为空,pphead也不为空,因为他是头指针plist的地址 // *pphead 不能断言,链表为空,也需要能插入 SLTNode* newnode = BuyLTNode(x); newnode->next = *pphead; *pphead = newnode; } //尾插 void SLTPushBack(SLTNode** pphead, SLTDataType x) { assert(pphead); SLTNode* newnode = BuyLTNode(x); //1.空链表 //2.非空链表 if (*pphead == NULL) { *pphead = newnode; //改变的结构体的指针plist(用结构体指针的地址) } else { SLTNode* tail = *pphead; while (tail->next != NULL) { tail = tail->next; } tail->next = newnode; //改变的结构体尾结点 } } //头删 void SLTPopFront(SLTNode** pphead) { //没有结点(空链表) assert(*pphead); //链表为空,不能头删 assert(pphead); //一个结点 if ((*pphead)->next == NULL) { free(*pphead); *pphead = NULL; } //多个结点 else { SLTNode* cur = *pphead; *pphead = cur->next; free(cur); } } //头删 //void SLTPopFront(SLTNode** pphead) //{ // //没有结点(空链表) // assert(*pphead); // assert(pphead); // // //一个结点 // //多个结点 // SLTNode* cur = *pphead; // *pphead = (*pphead)->next; // free(cur); //} //尾删 void SLTPopBack(SLTNode** pphead) { //没有结点(空链表) assert(*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; } } //查找 SLTNode* SLTFind(SLTNode* phead, SLTDataType x) { assert(phead); SLTNode* cur = phead; while (cur) { if (cur->data == x) { return cur; } else { cur = cur->next; } } return NULL; } //修改 void SLTModify(SLTNode* phead, SLTNode* pos, SLTDataType x) { assert(phead); assert(pos); pos->data = x; } //在pos位置之前插入数据 void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) { assert(pphead); assert(pos); //防止给的位置为 空 if (*pphead == pos) { SLTPushFront(pphead, x); } else { SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } SLTNode* newnode = BuyLTNode(x); prev->next = newnode; newnode->next = pos; } } //在pos位置之后插入数据 void SLTInsertAfter(SLTNode* pos, SLTDataType x) { assert(pos); //防止给的位置为 空 SLTNode* newnode = BuyLTNode(x); newnode->next = pos->next; pos->next = newnode; } //删除pos位置的值 void SLTErase(SLTNode** pphead, SLTNode* pos) { assert(pphead); assert(pos); //防止给的位置为 空 if (*pphead == pos) { SLTPopFront(pphead); } else { SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; } prev->next = pos->next; free(pos); } } //删除pos位置之后的值 void SLTEraseAfter(SLTNode* pos) { assert(pos); assert(pos->next); SLTNode* next = pos->next; pos->next = next->next; free(next); }
🥝Test.c
#include"SList.h" //头插测试 void TestSList01() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTDestroy(&plist); } //尾插测试 void TestSList02() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPushBack(&plist, 5); SLTPushBack(&plist, 6); SLTPushBack(&plist, 7); SLTPrint(plist); SLTDestroy(&plist); } //头删测试 void TestSList03() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTPopFront(&plist); SLTPrint(plist); SLTPopFront(&plist); SLTPrint(plist); SLTPopFront(&plist); SLTPrint(plist); SLTPopFront(&plist); SLTPrint(plist); SLTDestroy(&plist); } //尾删测试 void TestSList04() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTPopBack(&plist); SLTPrint(plist); SLTPopBack(&plist); SLTPrint(plist); SLTPopBack(&plist); SLTPrint(plist); SLTPopBack(&plist); SLTPrint(plist); SLTDestroy(&plist); } //查找修改测试 void TestSList05() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTNode* pos = SLTFind(plist, 3); if (pos) { SLTModify(plist, pos, 8); } SLTPrint(plist); SLTDestroy(&plist); } //在pos位置之前插入数据测试 void TestSList06() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTNode* pos = SLTFind(plist, 3); if (pos) { SLTInsert(&plist, pos, 30); } SLTPrint(plist); SLTDestroy(&plist); } //在pos位置之后插入数据测试 void TestSList07() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTNode* pos = SLTFind(plist, 2); if (pos) { SLTInsertAfter(pos, 20); } SLTPrint(plist); SLTDestroy(&plist); } //删除pos位置的值测试 void TestSList08() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTNode* pos = SLTFind(plist, 3); if (pos) { SLTErase(&plist,pos); } SLTPrint(plist); SLTDestroy(&plist); } //删除pos位置之后的值测试 void TestSList09() { SLTNode* plist = NULL; SLTPushFront(&plist, 1); SLTPushFront(&plist, 2); SLTPushFront(&plist, 3); SLTPushFront(&plist, 4); SLTPrint(plist); SLTNode* pos = SLTFind(plist, 2); if (pos) { SLTEraseAfter(pos); } SLTPrint(plist); SLTDestroy(&plist); } int main() { //TestSList01(); //TestSList02(); //TestSList03(); //TestSList04(); //TestSList05(); //TestSList06(); //TestSList07(); //TestSList08(); //TestSList09(); return 0; }
😍这期内容些许复杂,需要慢慢理解消化哦!
总结🥰
以上就是 【数据结构】单链表—C语言版 的全部内容啦🥳🥳🥳🥳
本文章所在【数据结构与算法】专栏,感兴趣的烙铁可以订阅本专栏哦🥳🥳🥳
前途很远,也很暗,但是不要怕,不怕的人面前才有路。💕💕💕
小的会继续学习,继续努力带来更好的作品😊😊😊
创作写文不易,还多请各位大佬uu们多多支持哦🥰🥰🥰