• 数据结构 - 链表 (三)


    这篇博客完成单链表的最后部分,包括单链表的查找,任意位置插入删除数据,以及动态内存的释放。

    1. 单链表的查找
    单链表的结构如下图所示,我们查找数据只需将链表遍历一遍是否有需要查找的数据,同时也要考虑链表初始为空的情况。

    1. SLTNode* STFind(SLTNode* phead, SLTDataType x)
    2. {
    3. SLTNode* cur = phead;
    4. while (cur != NULL)
    5. {
    6. if (cur->data == x)
    7. {
    8. return cur;
    9. }
    10. cur = cur->next;
    11. }
    12. return NULL;
    13. }
     2. 在 pos 位置 之前/之后 插入数据
     在此处我们考虑两种情况,一是 pos 位置处即为头结点位置,以及 pos 位置是中间结点的位置,如下图所示:

    第一种情况我们只需调用之前的头部插入数据的函数即可 ,第二种情况我们需要遍历到 pos 前一个位置,在此处插入结点即可。
    1. void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
    2. {
    3. assert(pphead);
    4. assert(pos);
    5. if (*pphead == pos)
    6. {
    7. SLPushFront(pphead, x); //调用头插函数
    8. }
    9. else
    10. {
    11. SLTNode* prev = *pphead;
    12. while (prev->next != pos)
    13. {
    14. prev = prev->next;
    15. }
    16. SLTNode* newnode = BuyLTNode(x);
    17. prev->next = newnode;
    18. newnode->next = pos;
    19. }
    20. }
     而则在 pos 位置之后插入数据则十分简单,直接在后面插入结点即可。代码如下:
    1. void SLInsertAfter(SLTNode* pos, SLTDataType x)
    2. {
    3. assert(pos);
    4. SLTNode* newnode = BuyLTNode(x);
    5. newnode->next = pos->next;
    6. pos->next = newnode;
    7. }
    3. 在 pos 位置/之后删除数据
    pos 位置删除数据数据同样判断两种情况,当 pos 位置是头结点时,调用头删函数即可,否则遍历到 pos 结点位置,然后跳过 pos 结点,指向下一个结点的地址,再 free(pos) 即可。
    1. void SLErase(SLTNode** pphead, SLTNode* pos)
    2. {
    3. assert(pphead);
    4. assert(pos);
    5. if (pos == *pphead)
    6. {
    7. SLPopFront(pphead);//头部删除数据
    8. }
    9. else
    10. {
    11. SLTNode* prev = *pphead;
    12. while (prev->next != pos)
    13. {
    14. prev = prev->next;
    15. }
    16. prev->next = pos->next;
    17. free(pos);
    18. }
    19. }
     删除 pos 位置之后的数据则十分简单,代码如下:
    1. void SLEraseAfter(SLTNode* pos)
    2. {
    3. assert(pos);
    4. assert(pos->next);
    5. SLTNode* next = pos->next;
    6. pos->next = next->next;
    7. free(next);
    8. }
     4. 内存释放
    free 每一个结点,phead 置空即可 ,代码如下:
    1. void SLDestory(SLTNode** pphead)
    2. {
    3. assert(pphead);
    4. SLTNode* cur = *pphead;
    5. while (cur)
    6. {
    7. SLTNode* next = cur->next;
    8. free(cur);
    9. cur = next;
    10. }
    11. *pphead = NULL;
    12. }
    5. 结果
    1. SLTNode* pos = STFind(plist,3);//data = 3 的结点
    2. SLInsert(&plist, pos, 100);//3 前插入100
    3. SLTPrint(plist);
    4. SLInsertAfter(pos, 200);//3 后插入200
    5. SLTPrint(plist);
    6. SLEraseAfter(pos);//删除 3 后面的 200
    7. SLTPrint(plist);
    8. SLErase(&plist,pos);//删除 3
    9. SLTPrint(plist);
    10. SLDestory(&plist);//内存释放


  • 相关阅读:
    Android NDK之使用 arm-v7a 汇编实现两数之和
    世微LED 大功率升压恒流驱动芯片 平板显示LED背光板灯串恒流控制器 AP9193
    rust std
    Nginx基础篇-Nginx的日志模块
    32 道 Spring 常见面试总结(附详细参考答案),我经常拿来面试别人
    Java实现单例模式(懒汉式和饿汉式)
    nginx php-fpm swoole
    深圳库卡机器人KR460控制柜维修快速解决
    redis为什么使用跳跃表而不是树
    【java核心技术】Java知识总结 -- 接口
  • 原文地址:https://blog.csdn.net/dgfghchhgc/article/details/136421188