单链表
- 一.概念
- 二.一些类型的创建
- 三.尾插
- 四.头插
- 五.头删尾删
- 六.打印链表
- 七.单链表查找,任意位置插入,任意位置删除
- 八.源代码
一.概念
该篇链表博客是按照工程项目的格式来记录的,与平常的算法链表有些许不同,注意区分。
二.一些类型的创建
三.尾插
因为需要凭空插入一个数,所以我们肯定需要新开辟一个节点(newnode)来存放需要插入的数。之后我们需要找到原链表的尾部再将其插入就可以了。
这里尤其需要注意的一个点是:我们增加操作如果链表为空时需要改变头节点(phead),因为phead是一级指针,所以我们传参需要二级指针。
Test.c
SList.h
SList.c
四.头插
因为头插必定会改变头节点所以同样需要使用二级指针。同时让插入的节点变为头节点。
Test.c
SLIst.h
SList.c
五.头删尾删
SList.h
SList.c
尾删
头删
六.打印链表
SList.h
SList.c
七.单链表查找,任意位置插入,任意位置删除
SList.h
SLiist.c
查找
在pos位置前面插入
将pos位置删除
八.源代码
test.c
#include"SList.h"
void TestList()
{
SListNode* phead = NULL;
//测试部分
}
int main()
{
TestList();
return 0;
}
SList.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define SLTDataType int
typedef struct {
SLTDataType data;//这里将int类型替换成链表类型以符合工程书写习惯
struct SListNode* next;
}SListNode;
void SLPushBack(SListNode** phead,SLTDataType x);//尾插
void SLPushFront(SListNode** phead, SLTDataType x);//头插
void SLPopBack(SListNode** phead);//尾删
void SLPopFront(SListNode** phead);//头删
void SLPrint(SListNode* phead);//打印
//查找
SListNode* SListFind(SListNode* phead, SLTDataType x);
void SListInsert(SListNode**pphead,SListNode* pos, SLTDataType x);//在pos位置前位置插入(注意pos是节点的指针)
void SListErase(SListNode**pphead,SListNode* pos);//删除pos位置
SList.c
#include"SList.h"
void SLPushBack(SListNode** pphead, SLTDataType x)//尾插
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));//开辟新节点来存放插入的数
if (newnode == NULL)//如果开辟失败则返回错误
{
perror("malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;//初始化新节点
if (*pphead == NULL)//注意*pphead就是phead
{
*pphead = newnode;
}//如果链表里没有数直接插入数
else
{
SListNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}//找到原链表尾部
tail->next = newnode;//插入新节点
}
}
void SLPushFront(SListNode** pphead, SLTDataType x)//头插
{
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));//开辟一个新节点
if (newnode == NULL)//判断是否开辟成功
{
perror("malloc fail");
}
newnode->data = x;
newnode->next = *pphead;//让新的节点指向原本的头节点
*pphead = newnode;//让新节点成为头节点
}
void SLPopBack(SListNode** pphead)//尾删
{
assert(*pphead!=NULL);//断言链表不能为空
//找尾
if ((*pphead)->next == NULL)//如果链表只有一个数
{
free(*pphead);//直接释放头节点
*pphead = NULL;
}
else
{
SListNode* tail = *pphead;
SListNode* prev = NULL;
while (tail->next != NULL)
{
prev = tail;
tail = tail->next;
}
free(tail);//直接删掉tail节点
tail = NULL;
prev->next = NULL;
}
}
void SLPopFront(SListNode** pphead)//头删
{
assert(*pphead != NULL);//链表不能为空
SListNode* first = *pphead;
*pphead = first->next;//直接让头节点变为第二个数
free(first);
first = NULL;
}
void SLPrint(SListNode* phead)//打印
{
SListNode* start = phead;
while (start != NULL)
{
printf("%d ", start->data);
start = start->next;
}
printf("NULL");
}
SListNode* SListFind(SListNode* phead, SLTDataType x)//查找
{
SListNode* cur = phead;
while (cur->data != x&&cur!=NULL)
{
cur = cur->next;
}
return cur;
}
void SListInsert(SListNode**pphead,SListNode* pos, SLTDataType x)//任意位置插入
{
if (pos == *pphead)
{
SLPushFront(pphead,x);//头插
}
else
{
SListNode* pre = *pphead;
while (pre->next != pos)//找到pos前面的位置
{
pre = pre->next;
}
SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));//开辟新节点
newnode->data = x;
newnode->next = pos;//初始化新节点
pre->next = newnode;//将pos前一个位置连接到新节点上
}
}
void SListErase(SListNode** pphead, SListNode* pos)//任意位置删除
{
if (pos == *pphead)
{
SLPopFront(pphead);//头删
}
else
{
SListNode* pre = *pphead;
while (pre->next != pos)//找到pos前面的位置
{
pre = pre->next;
}
pre->next = pos->next;//删除
free(pos);
}
}