本篇博客主要是单链表(无头单项不循环)的实现的代码分享
说明:因为此单链表无头(哨兵位),可以说成没有初始化也可以说初始化时没有一个有效地址作为单链表的起始地址 例如下面代码中的plist == NULL。
所以在后面函数(链表为空时,头插、尾插、插入)实现过程中需要将plist(单链表头结点地址)修改,就需要传址操作(在这里需要传单链表节点地址的地址),而且为了代码接口的一致性,在单链表函数实现中全部传了单链表节点地址的地址!
图解:
SLNode* plist = NULL;//只是定义了一个单向链表节点的地址,而且地址还==NULL
SLNodePushBack(&plist,1);
头文件Single List.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLNodeDataType;
typedef struct Single_Linked_ListNode
{
SLNodeDataType data;
struct Single_Linked_ListNode* next;
}SLNode;
//
void SLNodePushBack(SLNode** pphead, SLNodeDataType x);
void SLNodePushFront(SLNode** pphead, SLNodeDataType x);
void SLNodePopBack(SLNode** pphead);
void SLNodePopFront(SLNode** pphead);
SLNode* SLNodeBuyNode(SLNodeDataType x);
void SLNodePrint(SLNode** pphead);
SLNode* SLNodeFind(SLNode** pphead,SLNodeDataType x);
void SLNodeInsert(SLNode** pphead, SLNode* pos, SLNodeDataType x);
void SLNodeErase(SLNode** pphead, SLNode* pos);
void SLNodeInsertAfter(SLNode** pphead, SLNode* pos, SLNodeDataType x);
void SLNodeEraseAfter(SLNode** pphead, SLNode* pos);
void SListDestroy(SLNode** pphead)
源文件Single Link.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Single List.h"
SLNode* SLNodeBuyNode(SLNodeDataType x)
{
SLNode* tmp = malloc(sizeof(SLNode));
if (tmp == NULL)
{
perror("malloc fail!");
exit(1);
}
tmp->data = x;
tmp->next = NULL;
return tmp;
};
void SLNodePushBack(SLNode** pphead, SLNodeDataType x)
{
assert(pphead);
SLNode* pnewnode = SLNodeBuyNode(x);
//链表为空,新节点做头节点
if (*pphead == NULL)
{
*pphead = pnewnode;
return;
}
//链表不为空,找尾节点
SLNode* ptail= *pphead;
while (ptail->next != NULL)
{
ptail = ptail->next;
}
ptail->next = pnewnode;
};
void SLNodePushFront(SLNode** pphead, SLNodeDataType x)
{
assert(pphead);
SLNode* pnewnode = SLNodeBuyNode(x);
//链表为空,新节点做头节点
if (*pphead == NULL)
{
*pphead = pnewnode;
return;
}
//链表不为空
pnewnode->next = *pphead;
*pphead = pnewnode;
}
void SLNodePopBack(SLNode** pphead)
{
assert(pphead);
assert(*pphead);//确保有节点
//只有一个节点
if ((*pphead)->next == NULL)
{
free(*pphead);//置空前不要忘了释放空间
*pphead = NULL;
return;//不需要再走了
}
//多节点,找尾节点前一个节点
SLNode* ptailprev = *pphead;
while ((ptailprev->next->next) != NULL)
{
ptailprev = ptailprev->next;
}
free(ptailprev->next);
ptailprev->next = NULL;
}
void SLNodePopFront(SLNode** pphead)
{
assert(pphead);
assert(*pphead);//必须有节点
一个节点
//if ((*pphead)->next == NULL)
//{
// free(*pphead);
// *pphead = NULL;
// return;
//}
多个节点
SLNode* tmp = (*pphead)->next;
free(*pphead);
*pphead = tmp;
}
void SLNodePrint(SLNode** pphead)
{
SLNode* pcur = *pphead;
while (pcur)
{
printf("%d->",pcur->data);
pcur = pcur->next;
}
printf("NULL\n");
}
SLNode* SLNodeFind(SLNode** pphead,SLNodeDataType x)
{
assert(pphead);
//遍历链表
SLNode* pcur = *pphead;
while (pcur)
{
if (pcur->data == x)
{
return pcur;
}
pcur=pcur->next;
}
//没找到
return NULL;
}
void SLNodeInsert(SLNode** pphead, SLNode* pos, SLNodeDataType x)
{
assert(pphead);
assert(pos);
//链表不为空
assert(*pphead);
SLNode* pnewnode = SLNodeBuyNode(x);
//头节点插入
if (pos == *pphead)
{
SLNodePushFront(pphead,x);
return;
}
//其他节点
SLNode* prev = *pphead;
while (prev->next!=pos)
{
prev = prev->next;
}
prev->next = pnewnode;
pnewnode->next = pos;
}
void SLNodeErase(SLNode** pphead, SLNode* pos)
{
assert(pphead);
assert(pos);
assert(*pphead);
if (*pphead == pos)
{
SLNodePopFront(pphead);
return;
}
SLNode* prev= *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLNode* pnext = pos->next;
pos->next = NULL;
free(pos);
pos = NULL;
prev -> next = pnext;
}
void SLNodeInsertAfter(SLNode** pphead, SLNode* pos, SLNodeDataType x)
{
assert(pphead);
assert(pos);
SLNode* pnewnode = SLNodeBuyNode(x);
SLNode* pnext = pos->next;
pos->next = pnewnode;
pnewnode->next = pnext;
}
void SLNodeEraseAfter(SLNode** pphead, SLNode* pos)
{
assert(pphead);
assert(pos);
assert(pos->next);
//pos pnext pnextnext
SLNode* pnext = pos->next;
SLNode* pnextnext = pnext->next;
pos->next = pnextnext;
pnext->next = NULL;
free(pnext);
pnext = NULL;
}
void SListDestroy(SLNode** pphead)
{
assert(pphead);
assert(*pphead);
SLNode* pcur = *pphead;
while (pcur)
{
SLNode* next = pcur->next;
free(pcur);
pcur = next;
}
*pphead = NULL;
}
测试test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Single List.h"
int main()
{
SLNode* plist = NULL;
SLNodePushBack(&plist,1);
SLNodePushBack(&plist,2);
SLNodePushBack(&plist,3);
SLNodePushBack(&plist,4);
SLNodePushBack(&plist,5);
SLNodePrint(&plist);
SLNodePushFront(&plist, 100);
SLNodePushFront(&plist, 200);
SLNodePushFront(&plist, 300);
SLNodePushFront(&plist, 400);
SLNodePrint(&plist);
SLNodePopBack(&plist);
SLNodePopBack(&plist);
SLNodePrint(&plist);
SLNodePopFront(&plist);
SLNodePopFront(&plist);
SLNodePopFront(&plist);
SLNodePrint(&plist);
SLNode* findinex = SLNodeFind(&plist,100 );
if (findinex)
{
printf("找到了\n");
}
else
{
printf("未找到\n");
}
SLNodeInsert(&plist,findinex,1000);
SLNodePrint(&plist);
SLNodeErase(&plist,findinex);
SLNodePrint(&plist);
SLNode* findinex2 = SLNodeFind(&plist, 1000);
if (findinex2)
{
printf("找到了\n");
}
else
{
printf("未找到\n");
}
//SLNodeErase(&plist, findinex2);
SLNodePrint(&plist);
SLNodeInsertAfter(&plist, findinex2, 666);
SLNodePrint(&plist);
SLNode* findinex3 = SLNodeFind(&plist,1000);
if (findinex3)
{
printf("找到了\n");
}
else
{
printf("未找到\n");
}
SLNodeEraseAfter(&plist, findinex3);
SLNodePrint(&plist);
return 0;
SListDestroy(&plist);
}
这个博客如果对你有帮助,给博主一个免费的点赞就是最大的帮助❤
欢迎各位点赞,收藏和关注哦❤
如果有疑问或有不同见解,欢迎在评论区留言哦❤
后续我会一直分享双一流211西北大学本科生我自己的软件学习过程(C,数据结构,C++,Linux,MySQL)的学习干货以
及重要代码的分享