1. 程式人生 > >Leetcode 147 對連結串列進行插入排序

Leetcode 147 對連結串列進行插入排序

按照陣列插入排序的思路,需要把陣列分成以排序和未排序的兩部分:

每次從未排序的陣列中拿出一個插入已排序的陣列中,指到未排序陣列未空。在插入的過程中涉及到陣列的遍歷查詢,而陣列是可以按下標從後向前遍歷的:

void InsertSort(int a[], int n)
{
    for(int i=1;i<n;i++)
    {
        int value=a[i];
        int index=i-1;
        while(index>=0&&a[index]>value)
        {
            a[index+1]=a[index];
            index--;
        }
        a[index+1]=value;
    }
}

但單鏈表只能單向順序遍歷,因此必須用兩個指標來分別遍歷有序連結串列和未排序連結串列,因此必須先構建一個新連結串列作為有序連結串列最終返回:

/**
 * 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==NULL || head->next == NULL)
        return head;

    //創造一個新的連結串列頭部
    ListNode* pre = new ListNode(-1);
    //用一個臨時變數儲存頭節點
    ListNode* ans = pre;
    //cur是原連結串列上的指標
    ListNode* cur = head;
    while (cur != NULL) {
        //每次迴圈前重置pre為頭結點,這樣保證每次都從頭往後遍歷
        pre = ans;
        
        //當pre.next.val大於cur.val時停止迴圈
        while (pre->next != NULL && pre->next->val < cur->val) {
            pre = pre->next;
        }

        //pre->next->val 大於 cur->val,此時應該把cur插入到pre後
        //儲存原連結串列當前節點的下一節點
        ListNode* tmp = cur->next;
        //把cur插入到pre之後
        cur->next = pre->next;
        pre->next = cur;
        
        //cur指標後移一位
        cur = tmp;
    }
    return ans->next;
    }
};

發現上面的head賦值給cur 之後就再也沒用用過,所以乾脆直接用head來遍歷未排序陣列:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if(head==NULL || head->next == NULL)
            return head;

        ListNode* ans = new ListNode(-1);   
        while (head != NULL) {
            
            ListNode* tmp= head->next;
            ListNode* cur= ans;
            
            while (cur->next != NULL && cur->next->val < head->val) {
                cur = cur->next;
            }

            head->next = cur->next;
            cur->next = head;
            head = tmp;
        }
        return ans->next;
    }
};