Skip to content

Commit 75fd3cb

Browse files
committed
148 Sort List
1 parent 956217a commit 75fd3cb

File tree

5 files changed

+203
-0
lines changed

5 files changed

+203
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
+ [145 Binary Tree Postorder Traversal(后序遍历)](algorithms/BinaryTreePostorderTraversal)
8787
+ [146 LRU Cache(空间换时间)](algorithms/LRUCache)
8888
+ [147 Insertion Sort List(链表操作,插入排序)](algorithms/InsertionSortList)
89+
+ [148 Sort List(归并排序)](algorithms/SortList)
8990
+ [150 Evaluate Reverse Polish Notation(栈的应用)](algorithms/EvaluateReversePolishNotation)
9091
+ [151 Reverse Words in a String](algorithms/ReverseWordsinaString)
9192
+ [152 Maximum Product Subarray(DP)](algorithms/MaximumProductSubarray)

algorithms/SortList/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
## Sort List
2+
3+
Sort a linked list in O(n log n) time using constant space complexity.
4+
5+
## Solution
6+
7+
使用归并排序。
8+
9+
首先需要把链表分成左右两部分,使用快慢指针法找到中间节点
10+
11+
```cpp
12+
ListNode *slow = head;
13+
ListNode *fast = head,
14+
ListNode *prev = head; // 假设至少2个节点,因此while至少执行一次
15+
while (fast && fast->next) {
16+
prev = slow;
17+
slow = slow->next;
18+
fast = fast->next->next;
19+
}
20+
prev->next = nullptr; // 断开左右部分
21+
```
22+
23+
此时`left = head, right = slow`:
24+
25+
```cpp
26+
ListNode *left = head;
27+
ListNode *right = slow;
28+
```
29+
30+
分别调用mergeSort对左右部分排序:
31+
32+
```cpp
33+
left = mergeSort(left);
34+
right = mergeSort(right);
35+
```
36+
37+
然后合并左右两个部分即可:
38+
39+
```cpp
40+
ListNode *merged = merge(left, right);
41+
```
42+
43+
完整代码:
44+
45+
```cpp
46+
ListNode *mergeSort(ListNode *head) {
47+
if (!head || !head->next) // 少于2个节点直接返回
48+
return head;
49+
ListNode *slow = head;
50+
ListNode *fast = head;
51+
ListNode *prev = head; // 至少2个节点,因此while至少执行一次
52+
while (fast && fast->next) {
53+
prev = slow;
54+
slow = slow->next;
55+
fast = fast->next->next;
56+
}
57+
prev->next = nullptr;// 断开左右两部分
58+
ListNode *left = mergeSort(head);
59+
ListNode *right = mergeSort(slow);
60+
ListNode *merged = merge(left, right);
61+
return merged;
62+
}
63+
```
64+
65+
66+
合并两个链表可以使用迭代法,也可以使用递归法,下面是递归实现方法:
67+
68+
```cpp
69+
ListNode *merge(ListNode *l1, ListNode *l2) {
70+
if (l1 == nullptr)
71+
return l2;
72+
if (l2 == nullptr)
73+
return l1;
74+
if (l1->val <= l2->val) {
75+
l1->next = merge(l1->next, l2);
76+
return l1;
77+
} else {
78+
l2->next = merge(l1, l2->next);
79+
return l2;
80+
}
81+
}
82+
```

algorithms/SortList/in.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
5
2+
5 4 3 2 1
3+
5
4+
1 2 3 5 4
5+
5
6+
1 2 3 4 5
7+
1
8+
1
9+
5
10+
2 1 4 3 5

algorithms/SortList/list.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#include <iostream>
2+
#include <cstdio>
3+
#include <vector>
4+
#include <algorithm>
5+
#include <string>
6+
using namespace std;
7+
#include <stdlib.h>
8+
struct ListNode {
9+
int val;
10+
ListNode *next;
11+
ListNode(int x): val(x), next(nullptr) {}
12+
};
13+
class Solution {
14+
public:
15+
ListNode *sortList(ListNode *head) {
16+
return mergeSort(head);
17+
}
18+
private:
19+
ListNode *mergeSort(ListNode *head) {
20+
if (!head || !head->next)
21+
return head;
22+
ListNode *slow = head, *fast = head, *prev = head; // 至少2个节点,因此while至少执行一次
23+
while (fast && fast->next) {
24+
prev = slow;
25+
slow = slow->next;
26+
fast = fast->next->next;
27+
}
28+
prev->next = nullptr;
29+
ListNode *left = mergeSort(head);
30+
ListNode *right = mergeSort(slow);
31+
ListNode *merged = merge(left, right);
32+
return merged;
33+
}
34+
ListNode *merge(ListNode *l1, ListNode *l2) {
35+
if (l1 == nullptr)
36+
return l2;
37+
if (l2 == nullptr)
38+
return l1;
39+
if (l1->val <= l2->val) {
40+
l1->next = merge(l1->next, l2);
41+
return l1;
42+
} else {
43+
l2->next = merge(l1, l2->next);
44+
return l2;
45+
}
46+
}
47+
48+
};
49+
int getLength(ListNode *head)
50+
{
51+
int len = 0;
52+
ListNode *p = head;
53+
while (p) {
54+
++len;
55+
p = p->next;
56+
}
57+
return len;
58+
}
59+
void print(ListNode *head)
60+
{
61+
if (head == nullptr) {
62+
printf("NULL\n");
63+
return;
64+
}
65+
struct ListNode *p = head;
66+
while (p) {
67+
printf("%d ", p->val);
68+
p = p->next;
69+
}
70+
printf("\n");
71+
}
72+
ListNode * mk_list(ListNode **ha, int a[], int n)
73+
{
74+
if (n < 1)
75+
return nullptr;
76+
ListNode *p = new ListNode(a[0]);
77+
*ha = p;
78+
for (int i = 1; i < n; ++i) {
79+
ListNode *q = new ListNode(a[i]);
80+
p->next = q;
81+
p = q;
82+
}
83+
return p;
84+
}
85+
void free_list(struct ListNode *head)
86+
{
87+
struct ListNode *p = head;
88+
while (p) {
89+
struct ListNode *q = p->next;
90+
delete p;
91+
p = q;
92+
}
93+
}
94+
int main(int argc, char **argv)
95+
{
96+
Solution solution;
97+
int a[20], n;
98+
ListNode *head;
99+
while (cin >> n) {
100+
for (int i = 0; i < n; ++i)
101+
cin >> a[i];
102+
mk_list(&head, a, n);
103+
print(head);
104+
head = solution.sortList(head);
105+
print(head);
106+
cout << endl << endl;
107+
}
108+
return 0;
109+
}

algorithms/SortList/solve.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
list.cpp

0 commit comments

Comments
 (0)