前言
本篇讲述了单链表的相关知识,以及单链表增删查改的代码实现。
文章目录
- 前言
- 1.链表
- 1.1 链表的结构和概念
- 2.(增删查改)单链表的实现
- 2.1 打印链表
- 2.2 尾插
- 2.3 尾删
- 2.4 头插
- 2.5 头删
- 2.6 查找
- 2.7 在指定位置(pos)前插入
- 2.8 在指定位置(pos)删除
- 2.9 在指定位置(pos)后插入
- 2.10 在指定位置(pos)后删除
- 2.11 摧毁链表
1.链表
1.1 链表的结构和概念
概念如下: 链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
结构如下:
用代码可以这样表示:
struct SListNode
{
int val;
struct SListNode* next;
};
但是不属于结构体嵌套结构体!!!!!
2.(增删查改)单链表的实现
这里只展示自定义函数部分,查看完整代码可以进入我的gitee拷贝。
链接: 完整代码点这里
2.1 打印链表
void SLTPrint(SLNode* phead)
{
SLNode* cur = phead;
while (cur != NULL)
{
printf("%d ", cur->val);
cur = cur->next;
}
printf("NULL\n");
}
2.2 尾插
void SLTPushBack(SLNode** pphead, SLNDataType x)
{
SLNode* newnode = CreateNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
// 找尾
SLNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
2.3 尾删
void SLTPopBack(SLNode** pphead)
{
assert(*pphead);
// 1、一个节点
// 2、一个以上节点
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLNode* tail = *pphead;
while (tail->next->next != NULL)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
2.4 头插
void SLTPushFront(SLNode** pphead, SLNDataType x)
{
SLNode* newnode = CreateNode(x);
newnode->next = *pphead;
*pphead = newnode;
}
2.5 头删
void SLTPopFront(SLNode** pphead)
{
assert(*pphead);
// 一个以上节点 + 一个
SLNode* tmp = *pphead;
*pphead = (*pphead)->next;
free(tmp);
}
2.6 查找
SLNode* SLTFind(SLNode* phead, SLNDataType x)
{
SLNode* cur = phead;
while (cur != NULL)
{
if (cur->val == x)
{
return cur;
}
else
{
cur = cur->next;
}
}
return NULL;
}
2.7 在指定位置(pos)前插入
void SLTInsertpre(SLNode** pphead, SLNode* pos, SLNDataType x)
{
// 严格限定pos一定是链表里面的一个有效节点
assert(pphead);
assert(pos);
assert(*pphead);
if (*pphead == pos)
{
// 头插
SLTPushFront(pphead, x);
}
else
{
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLNode* newnode = CreateNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
2.8 在指定位置(pos)删除
void SLTErasepre(SLNode** pphead, SLNode* pos)
{
assert(pphead);
assert(*pphead);
assert(pos);
if (*pphead == pos)
{
// 头删
SLTPopFront(pphead);
}
else
{
SLNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
pos = NULL;
}
}
2.9 在指定位置(pos)后插入
void SLTInsertAfter(SLNode* pos, SLNDataType x)
{
assert(pos);
SLNode* newnode = CreateNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
2.10 在指定位置(pos)后删除
void SLTEraseAfter(SLNode* pos)
{
assert(pos);
assert(pos->next);
SLNode* tmp = pos->next;
pos->next = pos->next->next;
free(tmp);
tmp = NULL;
}
2.11 摧毁链表
void SLTDestroy(SLNode** pphead)
{
assert(pphead);
SLNode* cur = *pphead;
while (cur)
{
SLNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
链接: 完整代码点这里