• 单链表及其所有操作(无哨兵位)


    目录

    一、单链表结构的定义

    二、单链表结点的创建

    三、单链表打印

    四、单链表尾插

    五、单链表头插

    六、单链表尾删

    七、单链表头删

    九、单链表任意位置插入

    十、单链表任意位置删除

    十一、单链表任意位置后插入

    十二、单链表任意位置后删除

    十三、单链表任意位置插入(不提供链表头结点)


    一、单链表结构的定义

    1. //单链表结构的定义
    2. typedef int SLNDataType;//数据类型
    3. typedef struct SListNode {
    4. SLNDataType val;//结点数据域
    5. struct SListNode* next;//结点指针域
    6. }SLNode;

    二、单链表结点的创建

    1. //单链表结点的创建
    2. SLNode* CreateNode(SLNDataType x)
    3. {
    4. SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));//为新结点申请空间
    5. if (newnode == NULL)//申请失败
    6. {
    7. perror("malloc fail");
    8. exit(-1);
    9. }
    10. newnode->val = x;//新结点数据域
    11. newnode->next = NULL;//新结点指针域
    12. return newnode;
    13. }

    三、单链表打印

    1. //单链表的打印
    2. void SLTPrint(SLNode* phead)
    3. {
    4. SLNode* cur = phead;
    5. while (cur)
    6. {
    7. printf("%d->", cur->val);
    8. cur = cur->next;
    9. }
    10. if (cur == NULL)
    11. printf("NULL\n");
    12. }

    四、单链表尾插

    1. //单链表的尾插
    2. void SLTPushBack(SLNode** pphead, SLNDataType x)
    3. {
    4. assert(pphead);
    5. SLNode* newnode = CreateNode(x);
    6. //链表为空
    7. if (*pphead == NULL)
    8. {
    9. *pphead = newnode;
    10. }
    11. else//链表不为空
    12. {
    13. SLNode* tail = *pphead;
    14. while (tail->next)//找尾结点
    15. {
    16. tail = tail->next;
    17. }
    18. tail->next = newnode;//尾插
    19. }
    20. }

    五、单链表头插

    1. //单链表头插
    2. void SLTPushFront(SLNode** pphead, SLNDataType x)
    3. {
    4. assert(pphead);
    5. SLNode* newnode = CreateNode(x);
    6. newnode->next = *pphead;
    7. *pphead = newnode;
    8. //SLNode* newnode = CreateNode(x);
    9. 链表为空
    10. //if (*pphead == NULL)
    11. //{
    12. // *pphead = newnode;
    13. //}
    14. //else//链表不为空
    15. //{
    16. // SLNode* tmp = *pphead;
    17. // *pphead = newnode;
    18. // (*pphead)->next = tmp;
    19. //}
    20. }

    六、单链表尾删

    1. //单链表尾删
    2. void SLTPopBack(SLNode** pphead)
    3. {
    4. assert(pphead);
    5. assert(*pphead);//链表不能为空
    6. if ((*pphead)->next == NULL)//链表只有一个结点
    7. {
    8. free(*pphead);
    9. *pphead = NULL;
    10. }
    11. else//链表有多个结点
    12. {
    13. SLNode* tail = *pphead;
    14. SLNode* prev = NULL;
    15. while (tail->next != NULL)
    16. {
    17. prev = tail;
    18. tail = tail->next;
    19. }
    20. prev->next = NULL;
    21. free(tail);
    22. tail = NULL;
    23. }
    24. }

    七、单链表头删

    1. //单链表头删
    2. void SLTPopFront(SLNode** pphead)
    3. {
    4. assert(pphead);
    5. assert(*pphead);
    6. //SLNode* tmp = *pphead;
    7. //*pphead = (*pphead)->next;
    8. //free(tmp);
    9. //tmp = NULL;
    10. SLNode* tmp = (*pphead)->next;
    11. free(*pphead);
    12. *pphead = tmp;
    13. }

    八、单链表查找(返回找到的结点)

    1. //单链表查找(返回找到的结点)
    2. SLNode* SLTFind(SLNode* phead, SLNDataType x)
    3. {
    4. if (phead == NULL)
    5. return NULL;
    6. else
    7. {
    8. SLNode* cur = phead;
    9. while (cur)
    10. {
    11. if (cur->val == x)
    12. return cur;
    13. cur = cur->next;
    14. }
    15. return cur;//return NULL;
    16. }
    17. }

    九、单链表任意位置插入

    1. //单链表任意位置插入
    2. void SLTInsert(SLNode** pphead, SLNode* pos, SLNDataType x)
    3. {
    4. assert(pphead);
    5. assert(pos);//必须在有效结点处插入
    6. assert(*pphead);//如果pos是有效结点,那么链表一定不为空
    7. SLNode* newnode = CreateNode(x);
    8. if (*pphead == pos)//插入位置在头结点处
    9. {
    10. //头插
    11. SLTPushFront(pphead, x);
    12. }
    13. else
    14. {
    15. SLNode* cur = *pphead;
    16. while (cur->next != pos)//找插入位置的前一结点
    17. {
    18. cur = cur->next;
    19. }
    20. newnode->next = cur->next;
    21. cur->next = newnode;
    22. }
    23. }

    十、单链表任意位置删除

    1. //单链表任意位置删除
    2. void SLTErase(SLNode** pphead, SLNode* pos)
    3. {
    4. assert(pphead);
    5. assert(pos);//删除的必须是有效结点
    6. assert(*pphead);//链表不能为空
    7. if (*pphead == pos)//删除的结点是头结点
    8. {
    9. //头删
    10. SLTPopFront(pphead);
    11. }
    12. else
    13. {
    14. SLNode* cur = *pphead;
    15. while (cur->next != pos)//找删除结点的前一结点
    16. {
    17. cur = cur->next;
    18. }
    19. cur->next = pos->next;
    20. free(pos);
    21. pos = NULL;
    22. }
    23. }

    十一、单链表任意位置后插入

    1. //单链表任意位置后插入
    2. void SLTInsertAfter(SLNode* pos, SLNDataType x)
    3. {
    4. assert(pos);//必须是有效结点
    5. SLNode* newnode = CreateNode(x);
    6. newnode->next = pos->next;
    7. pos->next = newnode;
    8. }

    十二、单链表任意位置后删除

    1. //单链表任意位置后删除
    2. void SLTEraseAfter(SLNode* pos)
    3. {
    4. assert(pos);//必须是有效结点
    5. assert(pos->next);//如果pos是最后一个结点,那么pos的后一位置为空
    6. SLNode* tmp = pos->next;
    7. pos->next = tmp->next;
    8. free(tmp);
    9. tmp = NULL;
    10. }

    十三、单链表任意位置插入(不提供链表头结点)

    先进行任意位置后插入,再交换两个结点的值

    1. //单链表任意位置插入(不提供链表头结点)
    2. void SLTInsertNohead(SLNode* pos, SLNDataType x)
    3. {
    4. assert(pos);
    5. SLTInsertAfter(pos, x);//先在pos位置后插入
    6. pos->next->val = pos->val;
    7. pos->val = x;
    8. }
  • 相关阅读:
    核爆,字节跳动算法工程师,手写1000页数据算法笔记:Github已标星79k
    什么是模糊理论,基础,流程
    c++中dns解析
    Word处理控件Aspose.Words功能演示:在 Python 中将 Word 文档转换为 PNG、JPEG 或 BMP
    邮件营销效果如何加强?
    【以太网硬件十四】以太网的MAC是干什么的?
    MATLAB求解夏普利值
    java检测当前CPU负载状态的方法
    menuconfig 图形化配置原理说明三
    零信任的基本概念【新航海】
  • 原文地址:https://blog.csdn.net/2301_76197086/article/details/134174263