_莫相逢

导航

LeetCode 148 排序链表

题目:

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

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

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

解题思路:

可达到O(nlogn)的排序我们知道有三种,堆排、快排、二路归并。  这里由于是链表,堆排和归并都不太容易操作。所以这里我们用二路归并算法。

二路归并有递归的和非递归的,这里单链表,用非递归较为简单。因为递归要比较两个区间的大小,这里需要用到双指针。

代码:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* sortList(ListNode* head) {
12         if(head == NULL)
13             return NULL;
14         ListNode *p = head;
15         int len = 0;
16         while(p) {
17             len++;
18             p = p->next;
19         }
20 
21         ListNode *temp = new ListNode(0);
22         temp->next = head;
23 
24         int interval;
25         for(interval = 1; interval <= len; interval *= 2) { //从下往上归并
26             
27             ListNode *pre = temp;
28             ListNode *first = temp->next;
29             ListNode *second = temp->next;
30 
31             while(first && second) {
32                 int i = 0;
33                 while(i < interval && second) {
34                     second = second->next;
35                     i++;
36                 }
37                 int fvisit = 0;
38                 int svisit = 0;
39                 while(fvisit < interval && svisit < interval && first && second) {
40                     if(first->val < second->val) { //前指针较小,则把前指针装入放在前头
41                         pre->next = first;
42                         pre = first;
43                         first = first->next;
44                         fvisit++;
45                     }
46                     else {
47                         pre->next = second;
48                         pre = second;
49                         second = second->next;
50                         svisit++;
51                     }
52                 }
53                 while(fvisit < interval && first) {//剩下的较大的就依次接上就好
54                     pre->next = first;
55                     pre = first;
56                     first = first->next;
57                     fvisit++;
58                 }
59                 while(svisit < interval && second) {
60                     pre->next = second;
61                     pre = second;
62                     second = second->next;
63                     svisit++;
64                 }
65                 pre->next = second; //往后继续直到第一次排序结束
66                 first = second;
67             }
68         }
69         ListNode *ans = temp->next;
70         delete temp;
71         return ans;
72     }
73 };

 

posted on 2019-04-18 11:36  莫晓风  阅读(135)  评论(0编辑  收藏  举报