Insertion Sort List

Sort a linked list using insertion sort.

这道题目要求插入排序,插入排序的做法的正常做法是,对于当前要处理的数字,朝前查找在已排序数组中的位置. 

对于单向链表而言,无法朝前走,所以一个替换的选择是从头朝后走.直到后面的节点值大于当前处理的节点.

值得注意的有两点:1.插入时需要处理插入点前后位置的节点的链接,所以需要找到的是两个节点中的靠前的那个,即prev->next->val.

         2.每次处理当前节点使,如果该节点换了位置往前插,则已经有序数组的最后一位的指向发生了变化,所以每次定位在有序数组的最后一个节点,要处理的节点为该节点的next,即cur->next.

          所以要注意的是cur是有序数组的最后一位,只有这一位发生变化时,才需要修改cur.

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (head == nullptr || head -> next == nullptr) return head;
        ListNode dummy(-1);
        dummy.next = head;
        ListNode *cur= head;
        ListNode *prev = &dummy; //避免反复声明指针
        while (cur){ //目前处理的节点是cur->next,如果最后一个节点需要往前移动,那么会通过有序链表的最后一个节点间接处理.
            if (cur -> next && cur -> val > cur -> next -> val){ //加快处理速度
                while (prev -> next && prev->next->val < cur->next->val)
                    prev = prev->next;
                ListNode *tmp1 = cur -> next -> next;
                ListNode *tmp2 = prev -> next;
                prev -> next = cur->next;
                cur->next -> next  = tmp2;
                cur -> next = tmp1; //更新要处理的节点.
                prev = &dummy;
            }
            else
                cur = cur->next; //有序链表的最后一位发生了改变.
        }
        return dummy.next;
    }
        
};

空间复杂度O(1),时间复杂度O(n^2)

原文地址:https://www.cnblogs.com/sherylwang/p/5777773.html