Leetcode Sort List

Leetcode Sort List ,本算法为进行链表排序,本题提供两种解法,其中解法一是符合题目要求的,如下:

解法一:使用归并排序,使用O(nlg n)时间,O(1)空间,实现时,需要特别注意,我们是在链表上操作,因此除了操作部分,链表也不能与前后两部分断开,相关代码如下:

#include<iostream>
#include<vector>
/*
 * There used the merge sort algorithm to sort the linked list, and the
 * time using is O(nlg(n)) and the space using is O(1)
 */

using namespace std;
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        ListNode* cur = head;
        int count = 0;
        // Count the length of the linked list
        while (cur) {
            count ++;
            cur = cur->next;
        }
        // Insert an empty node for convenient
        ListNode* tmp = new ListNode(0);
        tmp->next = head;
        head = tmp;
        // Record the two parts of the merge process
        ListNode* merge_one = NULL;
        ListNode* merge_two = NULL;
        ListNode* pre = NULL;
        ListNode* end = NULL;
        // Meger the linked list lg(n) times
        for (int i = 1; i < count * 2; i *= 2) {
            pre = head;
            for (int j = 0; j < count; j += i * 2) {
                merge_one = pre->next;
                merge_two = pre->next;
                int k = i;
                for (; k > 0 && merge_two->next; k --) {
                    merge_two = merge_two->next;
                }
                // If the second part doesn't exist, just continue
                if ((merge_two->next == NULL && k != 0) || merge_two == NULL) {
                    continue;
                }
                // Merge the two parts
                pre = mergeList(merge_one, merge_two, i, pre);
            }
        }
        return head->next;
    }
    ListNode* mergeList(ListNode*& one, ListNode*& two, int length, ListNode* pre) {
        int count_one = 0;
        int count_two = 0;
        ListNode* cur = pre;
        // Merge the two parts
        while (count_one < length && count_two < length && two) {
            if (one->val > two->val) {
                cur->next = two;
                cur = cur->next;
                two = two->next;
                count_two ++;
            } else {
                cur->next = one;
                cur = cur->next;
                one = one->next;
                count_one ++;
            }
        }
        ListNode* temp;
        // If the first part left, just append it to the list
        if (count_one < length) {
            temp = one;
            cur->next = one;
            while (count_one < length) {
                temp = one;
                one = one->next;
                count_one ++;
            }
            // Link the new list with the left nodes
            temp->next = two;
            return temp;
        }
        // If the second part left, just append it to the list
        if (two && count_two < length) {
            temp = two;
            cur->next = two;
            while (count_two < length && two) {
                temp = two;
                two = two->next;
                count_two ++;
            }
            return temp;
        }
        return NULL;
    }
};

// Sample input: ./a.out argv1 argv2 ...
int main(int argc, char* argv[]) {
    Solution so;
    vector<string> test;
    ListNode* head = NULL;
    ListNode* cur = NULL;
    // Make the test linked list
    for (int i = 1; i <argc; i ++) {
        if (cur) {
            cur->next = new ListNode(atoi(argv[i]));
            cur = cur->next;
        } else {
            cur = new ListNode(atoi(argv[i]));
            head = cur;
        }
    }
    head = so.sortList(head);
    cur = head;
    while (cur) {
        cout<<cur->val<<" ";
        cur = cur->next;
    }
    cout<<endl;
    return 0;
}

解法二:使快速排序一样的方法,不过此方法需要进行递归,不符合题目要求,但是时间复杂度也为O(nlg n),相关代码如下:

#include<iostream>
#include<vector>

/*
 * There used the quik sort algorithm,
 */

using namespace std;
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if (!head) {
            return head;
        }
        // Insert an empty node for the convenient
        ListNode* tmp = new ListNode(0);
        tmp->next = head;
        head = tmp;
        sort(head, NULL);
        return head->next;
    }
    void sort(ListNode* head, ListNode* end) {
        if (!head->next || head->next == end) {
            return;
        }
        ListNode* anchor = head->next;
        ListNode* cur = head->next->next;
        ListNode* pre = head->next;
        // Move the node less than ahead, and left the equal or greater than
        while (cur != end) {
            if (cur->val < anchor->val) {
                pre->next = cur->next;
                cur->next = head->next;
                head->next = cur;
                cur = pre->next;
            } else {
                pre = cur;
                cur = cur->next;
            }
        }
        // Sort the first part
        sort(head, anchor);
        // Sort the second part
        sort(anchor, end);
    }
};

// Sample input: ./a.out argv1 argv2 ...
int main(int argc, char* argv[]) {
    Solution so;
    vector<string> test;
    ListNode* head = NULL;
    ListNode* cur = NULL;
    for (int i = 1; i <argc; i ++) {
        if (cur) {
            cur->next = new ListNode(atoi(argv[i]));
            cur = cur->next;
        } else {
            cur = new ListNode(atoi(argv[i]));
            head = cur;
        }
    }
    head = so.sortList(head);
    cur = head;
    while (cur) {
        cout<<cur->val<<" ";
        cur = cur->next;
    }
    cout<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值