无头结点单链表直接插入排序(王红梅分级抽象教学方法)

复制代码
struct ListNode 
{
    int val;
    struct ListNode* next;
};

typedef struct ListNode ListNode;
struct ListNode* insertionSortList(struct ListNode* head)
{
    // 如果链表为空或者链表只有一个元素,那就根本不用排序
    if (head == NULL || head->next == NULL)
        return head;
    // 创建一个新链表sorthead ,sorthead指向有序区第一个节点
    // 把原链表的第一个节点取下来放到新链表
    ListNode* sorthead = head;
    ListNode* cur = head->next; // 让cur指向原链表第二个节点
    sorthead->next = NULL;

    //  然后cur遍历链表,让cur得val去和soryhead的val作对比,
    // 如果cur小于sorthead,那就是头插
    // 如果 cur == 或者大于的话 那就是中间插入或者尾插,
    // 那就在遍历sorthead链表,让sortcur去遍历,让sortcur得val值去和cur得val值作对比
    // 让sortprev指向sortcur得上一个指针 
    // 如果小于,就在 sortprev和sortcur之间插入 
    // 如果大于,那就让sortcur往后走,继续对比
    // 如果出了循环,就说明cur的值最大,那就尾插到sort链表中
    while (cur)//cur指向未排序节点的第一个(cur指向无序区)
    {
        ListNode* next = cur->next; // next指向cur得下一个节点

        // 将cur插入sort链表的同时保持有序
       // 如果cur小于sorthead,那就是头插
        if (cur->val <= sorthead->val)//第一个节点之前插入
        {
            // 头插到sorthead链表
            cur->next = sorthead;
            sorthead = cur;
        }
        else // 中间插入或者尾插
        {
           // 让sortprev指向sortcur得上一个指针
            ListNode* sortprev = sorthead; // 指向sortcur得前一个指针
            ListNode* sortcur = sorthead->next;

            while (sortcur)
            {
                if (cur->val <= sortcur->val)
                {
                    // 中间插入// 如果小于,就在 sortprev和sortcur之间插入 
                    sortprev->next = cur;
                    cur->next = sortcur;
                    break;
                }
                else
                {// 如果大于,那就让sortcur往后走,继续对比
                    // 让sortcur继续迭代,遍历链表
                    sortprev = sortcur;
                    sortcur = sortcur->next;
                }

            }

            // 走到这里可能是cur得val值大于sorthead中的任何一个值
            // 也可能是前面break出循环
            // 尾插到链表
          // 如果出了循环,就说明cur的值最大,那就尾插到sort链表中
            if (sortcur == NULL) // 判断是不是遍历完链表了
            {
                sortprev->next = cur;
                cur->next = NULL;
            }

        }
        cur = next;//指向无序区第一个节点
    }
    
    return sorthead;
}

注意:单独处理第一个节点插入和最后一个节点后插入

思路:

1首先将原链表的第一个节点head取消来当做新链表的头节点sorthead,然后让sorthead的next = NULL,让cur指向原链表的第二个节点。(注意了,要提前判断head和head->next是否为NULL)

2然后让cur的val去和sorthead的val去做比较,如果小于的话直接头插,大于的话就要中间插入或者尾插

3中间插入或者尾插需要分类讨论,让sortcur指向sorthead->next,让sortprev指向sortcur得上一个节点。让sortcur去和cur做对比,如果sortcur大那就让cur插入在sortprev和sortcur之间,小的话就让sortcur继续遍历sorthead链表,当sortcur= NULL的时候,就说明cur是最大的,要尾插到链表中

4最后返回sorthead

关于链式存储结构的:有头节点和无头结点单链表直接插入排序,

重点学习:分析问题,以及如何解决问题

相关推荐
嘉友1 小时前
Redis zset数据结构以及时间复杂度总结(源码)
数据结构·数据库·redis·后端
蒙奇D索大2 小时前
【数据结构】图解图论:度、路径、连通性,五大概念一网打尽
数据结构·考研·算法·图论·改行学it
姜行运4 小时前
数据结构【链表】
c语言·开发语言·数据结构·链表
egoist20235 小时前
【C++指南】一文总结C++二叉搜索树
开发语言·数据结构·c++·c++11·二叉搜索树
lidashent6 小时前
数据结构和算法——汉诺塔问题
数据结构·算法
ん贤8 小时前
2023第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(真题&题解)(C++/Java题解)
java·c语言·数据结构·c++·算法·蓝桥杯
我的sun&shine15 小时前
高级数据结构03RB树
数据结构·b树
_GR17 小时前
2022年蓝桥杯第十三届C&C++大学B组真题及代码
c语言·数据结构·c++·算法·蓝桥杯·动态规划
快来卷java17 小时前
常见集合篇(二)数组、ArrayList与链表:原理、源码及业务场景深度解析
java·数据结构·链表·maven
Stardep18 小时前
算法学习11——滑动窗口——最大连续1的个数
数据结构·c++·学习·算法·leetcode·动态规划·牛客网