上篇博客我将基础的尾插、尾删、头插、头删逐一讲解了,这篇博客将对上篇博客进行收尾,讲一下指定位置操作增删以及查找这几个函数,其实大同小异:
一.查找函数:
查找函数其实就是一个简单的循环遍历,所以不加以过多赘述:
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
二.指定位置前插入函数:
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pos);
assert(pphead);
if (pos == *pphead)
{
SLTPushFront(pphead, x);
}
else
{
//找到pos前一个位置:
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
SLTNode* newnode = BuySLTNode(x);
prev->next = newnode;
newnode->next = pos;
}
}
代码解释:
头插特殊处理:
if (pos == *pphead) { SLTPushFront(pphead, x); }
- 若在头节点前插入,调用专门的头插函数
- 确保头指针正确更新
查找前驱节点:
SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; }
- 从头节点开始遍历,寻找
pos
的前驱节点 - 若
pos
是头节点,此循环不会执行
- 从头节点开始遍历,寻找
插入新节点:
SLTNode* newnode = BuySLTNode(x); prev->next = newnode; newnode->next = pos;
- 创建新节点并连接到链表中
- 指针操作顺序正确,不会破坏链表结构
三.在指定位置删除函数:
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead);
assert(pos);
if (*pphead == pos)
{
SLTPopFront(pphead);
}
else
{
//找到pos前一个位置;
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
代码解释:
头删特殊处理:
if (*pphead == pos) { SLTPopFront(pphead); }
- 若删除头节点,调用专门的头删函数
- 确保头指针正确更新
查找前驱节点:
SLTNode* prev = *pphead; while (prev->next != pos) { prev = prev->next; }
- 从头节点开始遍历,寻找
pos
的前驱节点 - 若
pos
是头节点,此循环不会执行
- 从头节点开始遍历,寻找
删除节点:
prev->next = pos->next; free(pos);
- 调整前驱节点指针跳过
pos
- 释放
pos
节点的内存
- 调整前驱节点指针跳过
四.指定位置之后插入函数:
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuySLTNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
较为简单,不加以赘述;
五.指定位置之后删除函数:
void SLTEraseAfter(SLTNode* pos)
{
assert(pos);
assert(pos->next);
SLTNode* del = pos->next;
pos->next = del->next;
free(del);
del = NULL;
}
较为简单,不加以赘述;
六.函数复用:
当写出指定位置操作的几个函数以后,之前的那几个操作函数就可以直接套用指定位置的函数;
具体位置怎么设定留给你们自己思考一下,函数的复用我会在下一篇双向链表花一定的篇幅。
其实,要想快速的写出链表,都是先写指定位置函数,然后再去复用实现头尾的操作。
单链表一开始理解确实是有点困难的,但是一旦理解了以后,后续的双向链表之类的就变得简单了。虽然链表有很多种类,但是只要理解了单链表以后,其他的除了结构比单链表复杂以外难度远不及单链表!!!