Sort List (LeetCode)

Question:

https://oj.leetcode.com/problems/sort-list/

 

解答:

排序基本上就是heapsort, mergesort和quicksort。因为是linked list而且不能用额外的空间,所以用mergesort,因为merge sort的合并可以in place进行。quicksort需要在index之间跳来跳去。

第一次在recursive函数里用了一个pointer,记录当前linked list后面接着的node。后来看了别人的解法,其实可以直接对head指针进行操作,每访问一次就head=head->next,这样子head永远是下一个要sort的子linked list的开始。

注意在head变成head->next后,原来的head->next需要设成NULL.

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        
        int n = 0;
        
        ListNode* curr = head;
        while (curr)
        {
            n++;
            curr = curr->next;
        }
        
        if (n == 0)
            return NULL;
        
        return mergeSort(head, n);
        
        ListNode* nextNode = NULL;
        return mergeSort(head, n, nextNode);
    }
    
    ListNode* mergeSort(ListNode*& head, int n)
    {
        if (n == 1)
        {
            ListNode* newHead = head;
            head = head->next;
            newHead->next = NULL;
            return newHead;
        }
        
        ListNode* left = mergeSort(head, n/2);
        ListNode* right = mergeSort(head, n-n/2);
        
        ListNode* curr = NULL;
        ListNode* newHead = NULL;
        
        while (left || right)
        {
            bool leftFirst = false;
            
            if (left)
                leftFirst = (right ? left->val < right->val : true);
            else
                leftFirst = false;

            if (!curr)
            {
                curr = leftFirst ? left : right;
                newHead = curr;
            }
            else
            {
                curr->next = leftFirst ? left : right;
                curr = curr->next;
            }
            
            if (leftFirst)
                left = left->next;
            else
                right = right->next;
        }     
        
     
        return newHead;
    }
    
    ListNode* mergeSort(ListNode* head, int n, ListNode*& nextNode)
    {
        if (n == 1)
        {
            nextNode = head->next;
            head->next = NULL;
            return head;
        }
        
        ListNode* left = mergeSort(head, n/2, nextNode);
        ListNode* right = mergeSort(nextNode, n-n/2, nextNode);
        
        ListNode* curr = NULL;

        while (left || right)
        {
            bool leftFirst = false;
            
            if (left)
                leftFirst = (right ? left->val < right->val : true);
            else
                leftFirst = false;

            if (!curr)
            {
                curr = leftFirst ? left : right;
                head = curr;
            }
            else
            {
                curr->next = leftFirst ? left : right;
                curr = curr->next;
            }
            
            if (leftFirst)
                left = left->next;
            else
                right = right->next;
        }
        

         return head;
    }
};

 

posted @ 2014-11-11 13:52  smileheart  阅读(173)  评论(0编辑  收藏  举报