入门级题解147. 对链表进行插入排序

对链表进行插入排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (head == nullptr) {
            return head;
        }

        ListNode* dummyHead = new ListNode(0);
        ListNode* prev = dummyHead;

        ListNode* q = head;

        ListNode* next = q->next;
        q->next = prev->next;
        prev->next = q;
        prev = dummyHead;//prev一直遍历的,如果不这样下次会在他当前位置开始遍历,不会从头开始
        q = next;

        while(q){
            while(prev->next && q->val > prev->next->val){
                prev = prev->next;
            }
            ListNode* next = q->next;
            q->next = prev->next;
            prev->next = q;
            prev = dummyHead;//prev一直遍历的,如果不这样下次会在他当前位置开始遍历,不会从头开始
            q = next;
        }
        return dummyHead->next;
    }
};

在这里插入图片描述

思路的实现总是有点偏差:

以 1 2 3 4 5为例
下面是错误思路

思路:先把head的头节点独立出来,1 ,然后建dummy = 0 1,然后遍历2 3 4 5,同时遍历0
1,用next比较值,插入,这里有个特别大的错误思路,我以为小于就插在前面,正确的应该是:

插入排序,小于应该继续遍历而非插在前面,只有大于了才需要插在后面。

而且我对这个思路的实现也总是犯错。。。。
最近脑子昏沉沉的,应该先考虑特殊情况:空链表返回即可

总结:插入排序,以链表0->num1->num2->num3->num4为例我是先用哑节点和head的头节点num1组成一个 0->num1的链表dummy,然后这时候的p就是num2->num3->num4,遍历p,当p=num2时,遍历dummy,如果num2大于dummy当前节点下一个节点的值,就移动dummy到下一个,直到出现num2小于dummy当前节点下一个节点的值,这时候就把num2插入当前节点的后面
之所以要用next来比较,就是怕如果直接小于全部的,链表的前插是不方便的,所以用的next

ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;

下面代码作用,最后要返回dummyHead->next

ListNode* pre = dummyHead;,不能改变dummyHead
class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (head == nullptr) return head;

        ListNode* dummyHead = new ListNode(0); // 定一个虚拟头结点
        ListNode* cur = head;
        ListNode* pre = dummyHead;

        while (cur != nullptr) {
            while (pre->next != nullptr && pre->next->val < cur->val) {
                pre = pre->next;
            }
            // 在pre和prenext之间插入数据
            ListNode* next = cur->next; // 步骤一:保存curnext
            cur->next = pre->next;      // 步骤二 当前head的节点的next指向排好序的大于链表
            pre->next = cur;            // 步骤三 小于部分指向当前节点
            pre = dummyHead;            // 步骤四:这时候dummyhead已经插入刚才那个了,pre重新指向虚拟头结点来找下一个插入位置
            cur = next;                 // 步骤五:cur的前一个节点的下一个节点指向保存的next
        }
        return dummyHead->next;
    }
};

作者:carlsun-2
链接:https://leetcode-cn.com/problems/insertion-sort-list/solution/147-kao-cha-lian-biao-zong-he-cao-zuo-xiang-jie-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

官方这个题解真够晕的

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        
        ListNode* lastSorted = head;
        ListNode* curr = head->next;
        
        while (curr != nullptr) {
            if (lastSorted->val <= curr->val) {
                lastSorted = lastSorted->next;
            } else {
                ListNode *prev = dummyHead;
                
                while (prev->next->val <= curr->val) {
                    prev = prev->next;
                }
                
                lastSorted->next = curr->next;
                curr->next = prev->next;
                prev->next = curr;
            }
            
            curr = lastSorted->next;
        }
        return dummyHead->next;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值