Skip to content

Commit 03481b8

Browse files
author
lucifer
committed
feat: 手撕算法之排序
1 parent 297c514 commit 03481b8

File tree

3 files changed

+302
-0
lines changed

3 files changed

+302
-0
lines changed

‎src/codeTemplates/hand-writing.js

+299
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
module.exports = {
2+
logo: require("../imgs/hand-writing.svg"),
3+
title: "手撕算法",
4+
list: [
5+
{
6+
text: "数组排序",
7+
problems: [
8+
{
9+
id: "sort-an-array",
10+
title: "912. 排序数组",
11+
},
12+
],
13+
codes: [
14+
{
15+
language: "py",
16+
text: `
17+
# 1. 归并排序(推荐!其他排序方法都不推荐在竞赛中使用)
18+
# 归并排序乞丐版
19+
class Solution:
20+
def sortArray(self, nums: List[int]) -> List[int]:
21+
def mergeSort(l, r):
22+
if l >= r:
23+
return
24+
mid = (l + r) // 2
25+
mergeSort(l, mid)
26+
mergeSort(mid + 1, r)
27+
temp = []
28+
i, j = l, mid + 1
29+
while i <= mid and j <= r:
30+
if nums[i] < nums[j]:
31+
temp.append(nums[i])
32+
i += 1
33+
else:
34+
temp.append(nums[j])
35+
j += 1
36+
while i <= mid:
37+
temp.append(nums[i])
38+
i += 1
39+
while j <= r:
40+
temp.append(nums[j])
41+
j += 1
42+
nums[l : r + 1] = temp
43+
44+
mergeSort(0, len(nums) - 1)
45+
return nums
46+
# 归并排序优化版
47+
class Solution:
48+
def sortArray(self, nums: List[int]) -> List[int]:
49+
temp = [0] * len(nums)
50+
51+
def mergeSort(l, r):
52+
if l >= r:
53+
return
54+
mid = (l + r) // 2
55+
mergeSort(l, mid)
56+
mergeSort(mid + 1, r)
57+
i, j = l, mid + 1
58+
k = 0
59+
while i <= mid and j <= r:
60+
if nums[i] < nums[j]:
61+
temp[k] = nums[i]
62+
i += 1
63+
else:
64+
temp[k] = nums[j]
65+
j += 1
66+
k += 1
67+
while i <= mid:
68+
temp[k] = nums[i]
69+
i += 1
70+
k += 1
71+
while j <= r:
72+
temp[k] = nums[j]
73+
j += 1
74+
k += 1
75+
nums[l : r + 1] = temp[: r - l + 1]
76+
77+
mergeSort(0, len(nums) - 1)
78+
return nums
79+
80+
# 2. 快速排序
81+
# 快速排序乞丐版
82+
class Solution:
83+
def sortArray(self, nums: List[int]) -> List[int]:
84+
temp = [0] * len(nums)
85+
86+
def quickSort(nums):
87+
if not nums: return []
88+
pivot = nums[0]
89+
nums = nums[1:]
90+
l = quickSort([num for num in nums if num <= pivot])
91+
r = quickSort([num for num in nums if num > pivot])
92+
return l + [pivot] + r
93+
94+
return quickSort(nums)
95+
# 快速排序优化版
96+
class Solution:
97+
def sortArray(self, nums: List[int]) -> List[int]:
98+
temp = [0] * len(nums)
99+
100+
def partition(l, r):
101+
pivot = nums[l]
102+
103+
while l < r:
104+
while l < r and nums[r] >= pivot:
105+
r -= 1
106+
nums[l] = nums[r]
107+
while l < r and nums[l] <= pivot:
108+
l += 1
109+
nums[r] = nums[l]
110+
nums[l] = pivot
111+
return l
112+
113+
def quickSort(l, r):
114+
if l >= r:
115+
return
116+
pivot = partition(l, r)
117+
quickSort(l, pivot - 1)
118+
quickSort(pivot + 1, r)
119+
120+
quickSort(0, len(nums) - 1)
121+
return nums
122+
123+
# 3. 插入排序
124+
class Solution:
125+
def sortArray(self, nums: List[int]) -> List[int]:
126+
n = len(nums)
127+
for i in range(1, n):
128+
t = nums[i]
129+
j = i - 1
130+
while j > -1 and nums[j] > t:
131+
nums[j + 1] = nums[j]
132+
j -= 1
133+
nums[j + 1] = t
134+
return nums
135+
136+
# 4. 选择排序
137+
class Solution:
138+
def sortArray(self, nums: List[int]) -> List[int]:
139+
n = len(nums)
140+
for i in range(n - 1):
141+
k = i
142+
for j in range(i + 1, n):
143+
if nums[j] < nums[k]:
144+
k = j
145+
nums[i], nums[k] = nums[k], nums[i]
146+
return nums
147+
148+
# 5. 冒泡排序
149+
class Solution:
150+
def sortArray(self, nums: List[int]) -> List[int]:
151+
n = len(nums)
152+
for i in range(n):
153+
for j in range(i + 1, n):
154+
if nums[j] < nums[i]:
155+
nums[i], nums[j] = nums[j], nums[i]
156+
return nums
157+
158+
`,
159+
},
160+
],
161+
},
162+
{
163+
text: "链表排序",
164+
problems: [
165+
{
166+
id: "sort-list",
167+
title: "148. 排序链表",
168+
},
169+
],
170+
codes: [
171+
{
172+
language: "py",
173+
text: `
174+
# 1. 归并排序(推荐!其他排序方法都不推荐在竞赛中使用)
175+
class Solution:
176+
def sortList(self, head: ListNode) -> ListNode:
177+
def mergeSort(head: ListNode) -> ListNode:
178+
if not head or not head.next:
179+
return head
180+
dummyHead = ListNode(-1)
181+
dummyHead.next = head
182+
slow, fast = dummyHead, head
183+
while fast and fast.next:
184+
slow = slow.next
185+
fast = fast.next.next
186+
nxt = slow.next
187+
slow.next = None
188+
return merge(mergeSort(head), mergeSort(nxt))
189+
190+
def merge(head1: ListNode, head2: ListNode) -> ListNode:
191+
dummyHead = ListNode(-1)
192+
temp, l1, l2 = dummyHead, head1, head2
193+
while l1 and l2:
194+
if l1.val <= l2.val:
195+
temp.next = l1
196+
l1 = l1.next
197+
else:
198+
temp.next = l2
199+
l2 = l2.next
200+
temp = temp.next
201+
if l1:
202+
temp.next = l1
203+
elif l2:
204+
temp.next = l2
205+
return dummyHead.next
206+
207+
return mergeSort(head)
208+
# 2. 快速排序
209+
class Solution:
210+
def sortList(self, head):
211+
# 最坏情况也是 n ^ 2 ,因此面试或者竞赛不建议使用
212+
def quickSort(head, end):
213+
214+
if head != end:
215+
pivot = partition(head, end)
216+
quickSort(head, pivot)
217+
quickSort(pivot.next, end)
218+
219+
def partition(head, end):
220+
# p1是写指针,p2是读指针
221+
# 最终 p1 是大的链表的头, head 是小的链表的头
222+
pivot_val = head.val
223+
p1, p2 = head, head.next
224+
225+
while p2 != end:
226+
if p2.val < pivot_val:
227+
# 相当于数组的 append 方法
228+
p1 = p1.next
229+
p1.val, p2.val = p2.val, p1.val
230+
p2 = p2.next
231+
head.val, p1.val = p1.val, pivot_val
232+
return p1
233+
234+
quickSort(head, None)
235+
return head
236+
# 3. 插入排序
237+
class Solution:
238+
def sortList(self, head):
239+
if head == None or head.next == None:
240+
return head
241+
242+
dummy = ListNode(-1)
243+
dummy.next = head
244+
pre = dummy
245+
cur = head
246+
while cur:
247+
# 准备将 last 插入到合适位置
248+
last = cur.next
249+
if last and last.val < cur.val:
250+
# 从 dummy 到 cur 线性遍历找第一个满足条件的位置并插入
251+
while pre.next and pre.next.val < last.val:
252+
pre = pre.next
253+
tmp = pre.next
254+
pre.next = last
255+
cur.next = last.next # 别忘了这个,否则成环
256+
last.next = tmp
257+
pre = dummy
258+
else:
259+
cur = last
260+
261+
return dummy.next
262+
# 4. 选择排序
263+
class Solution:
264+
def sortList(self, head):
265+
temp = head
266+
267+
while temp:
268+
min_node = temp
269+
r = temp.next
270+
while r:
271+
if min_node.val > r.val:
272+
min_node = r
273+
r = r.next
274+
temp.val, min_node.val = min_node.val, temp.val
275+
temp = temp.next
276+
return head
277+
# 5. 冒泡排序
278+
class Solution:
279+
def sortList(self, head):
280+
if not head:
281+
return None
282+
swaped = True
283+
while swaped:
284+
swaped = False
285+
temp = head
286+
while temp.next:
287+
if temp.val > temp.next.val:
288+
swaped = True
289+
temp.val, temp.next.val = temp.next.val, temp.val
290+
temp = temp.next
291+
return head
292+
293+
`,
294+
},
295+
],
296+
},
297+
],
298+
// link: "",
299+
};

‎src/codeTemplates/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import slidingWindow from "./sliding-window";
77
import segmemntTree from "./segmentTree";
88
import heap from "./heap";
99
import preSum from "./preSum";
10+
import handWriting from "./hand-writing";
1011
export default [
1112
preSum,
1213
binarySearch,
@@ -17,4 +18,5 @@ export default [
1718
trie,
1819
uf,
1920
segmemntTree,
21+
handWriting,
2022
];

‎src/imgs/hand-writing.svg

+1
Loading

0 commit comments

Comments
 (0)