Skip to content

Commit 3d98cb5

Browse files
committed
go -> python
1 parent 80c0a19 commit 3d98cb5

4 files changed

Lines changed: 206 additions & 122 deletions

File tree

‎basic_algorithm/heapsort.py‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
def heap_adjust(A, start=0, end=None):
2+
if end is None:
3+
end = len(A)
4+
5+
while start is not None and start < end // 2:
6+
l, r = start * 2 + 1, start * 2 + 2
7+
swap = None
8+
9+
if A[l] > A[start]:
10+
swap = l
11+
if r < end and A[r] > A[start] and (swap is None or A[r] > A[l]):
12+
swap = r
13+
14+
if swap is not None:
15+
A[start], A[swap] = A[swap], A[start]
16+
17+
start = swap
18+
19+
return
20+
21+
def heapsort(A):
22+
23+
# construct max heap
24+
n = len(A)
25+
for i in range(n // 2 - 1, -1, -1):
26+
heap_adjust(A, i)
27+
28+
# sort
29+
for i in range(n - 1, 0, -1):
30+
A[0], A[i] = A[i], A[0]
31+
heap_adjust(A, end=i)
32+
33+
return A
34+
35+
# test
36+
if __name__ == '__main__':
37+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
38+
print(a)
39+
print(heapsort(a))

‎basic_algorithm/mergesort.py‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
def merge(A, B):
2+
C = []
3+
i, j = 0, 0
4+
while i < len(A) and j < len(B):
5+
if A[i] <= B[j]:
6+
C.append(A[i])
7+
i += 1
8+
else:
9+
C.append(B[j])
10+
j += 1
11+
12+
if i < len(A):
13+
C += A[i:]
14+
15+
if j < len(B):
16+
C += B[j:]
17+
18+
return C
19+
20+
def mergsort(A):
21+
n = len(A)
22+
if n < 2:
23+
return A[:]
24+
25+
left = mergsort(A[:n // 2])
26+
right = mergsort(A[n // 2:])
27+
28+
return merge(left, right)
29+
30+
if __name__ == '__main__':
31+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
32+
print(a)
33+
print(mergsort(a))

‎basic_algorithm/quicksort.py‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
def partition(A, start, end):
2+
if start >= end:
3+
return
4+
5+
l, r = start, end - 1
6+
while l < r:
7+
while l < r and A[l] <= A[end]:
8+
l += 1
9+
while l < r and A[r] >= A[end]:
10+
r -= 1
11+
12+
A[l], A[r] = A[r], A[l]
13+
14+
swap = r + int(A[r] < A[end])
15+
16+
A[end], A[swap] = A[swap], A[end]
17+
18+
partition(A, swap + 1, end)
19+
partition(A, start, swap - 1)
20+
21+
return
22+
23+
def quicksort(A):
24+
partition(A, 0, len(A) - 1)
25+
return A
26+
27+
if __name__ == '__main__':
28+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
29+
print(a)
30+
print(quicksort(a))

‎basic_algorithm/sort.md‎

Lines changed: 104 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -4,84 +4,75 @@
44

55
### 快速排序
66

7-
```go
8-
func QuickSort(nums []int) []int {
9-
// 思路:把一个数组分为左右两段,左段小于右段
10-
quickSort(nums, 0, len(nums)-1)
11-
return nums
12-
13-
}
14-
// 原地交换,所以传入交换索引
15-
func quickSort(nums []int, start, end int) {
16-
if start < end {
17-
// 分治法:divide
18-
pivot := partition(nums, start, end)
19-
quickSort(nums, 0, pivot-1)
20-
quickSort(nums, pivot+1, end)
21-
}
22-
}
23-
// 分区
24-
func partition(nums []int, start, end int) int {
25-
// 选取最后一个元素作为基准pivot
26-
p := nums[end]
27-
i := start
28-
// 最后一个值就是基准所以不用比较
29-
for j := start; j < end; j++ {
30-
if nums[j] < p {
31-
swap(nums, i, j)
32-
i++
33-
}
34-
}
35-
// 把基准值换到中间
36-
swap(nums, i, end)
37-
return i
38-
}
39-
// 交换两个元素
40-
func swap(nums []int, i, j int) {
41-
t := nums[i]
42-
nums[i] = nums[j]
43-
nums[j] = t
44-
}
7+
```Python
8+
def partition(A, start, end):
9+
if start >= end:
10+
return
11+
12+
l, r = start, end - 1
13+
while l < r:
14+
while l < r and A[l] <= A[end]:
15+
l += 1
16+
while l < r and A[r] >= A[end]:
17+
r -= 1
18+
19+
A[l], A[r] = A[r], A[l]
20+
21+
swap = r + int(A[r] < A[end])
22+
23+
A[end], A[swap] = A[swap], A[end]
24+
25+
partition(A, swap + 1, end)
26+
partition(A, start, swap - 1)
27+
28+
return
29+
30+
def quicksort(A):
31+
partition(A, 0, len(A) - 1)
32+
return A
33+
34+
if __name__ == '__main__':
35+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
36+
print(a)
37+
print(quicksort(a))
4538
```
4639

4740
### 归并排序
4841

49-
```go
50-
func MergeSort(nums []int) []int {
51-
return mergeSort(nums)
52-
}
53-
func mergeSort(nums []int) []int {
54-
if len(nums) <= 1 {
55-
return nums
56-
}
57-
// 分治法:divide 分为两段
58-
mid := len(nums) / 2
59-
left := mergeSort(nums[:mid])
60-
right := mergeSort(nums[mid:])
61-
// 合并两段数据
62-
result := merge(left, right)
63-
return result
64-
}
65-
func merge(left, right []int) (result []int) {
66-
// 两边数组合并游标
67-
l := 0
68-
r := 0
69-
// 注意不能越界
70-
for l < len(left) && r < len(right) {
71-
// 谁小合并谁
72-
if left[l] > right[r] {
73-
result = append(result, right[r])
74-
r++
75-
} else {
76-
result = append(result, left[l])
77-
l++
78-
}
79-
}
80-
// 剩余部分合并
81-
result = append(result, left[l:]...)
82-
result = append(result, right[r:]...)
83-
return
84-
}
42+
```Python
43+
def merge(A, B):
44+
C = []
45+
i, j = 0, 0
46+
while i < len(A) and j < len(B):
47+
if A[i] <= B[j]:
48+
C.append(A[i])
49+
i += 1
50+
else:
51+
C.append(B[j])
52+
j += 1
53+
54+
if i < len(A):
55+
C += A[i:]
56+
57+
if j < len(B):
58+
C += B[j:]
59+
60+
return C
61+
62+
def mergsort(A):
63+
n = len(A)
64+
if n < 2:
65+
return A[:]
66+
67+
left = mergsort(A[:n // 2])
68+
right = mergsort(A[n // 2:])
69+
70+
return merge(left, right)
71+
72+
if __name__ == '__main__':
73+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
74+
print(a)
75+
print(mergsort(a))
8576
```
8677

8778
### 堆排序
@@ -98,55 +89,46 @@ func merge(left, right []int) (result []int) {
9889

9990
核心代码
10091

101-
```go
102-
package main
103-
104-
func HeapSort(a []int) []int {
105-
// 1、无序数组a
106-
// 2、将无序数组a构建为一个大根堆
107-
for i := len(a)/2 - 1; i >= 0; i-- {
108-
sink(a, i, len(a))
109-
}
110-
// 3、交换a[0]和a[len(a)-1]
111-
// 4、然后把前面这段数组继续下沉保持堆结构,如此循环即可
112-
for i := len(a) - 1; i >= 1; i-- {
113-
// 从后往前填充值
114-
swap(a, 0, i)
115-
// 前面的长度也减一
116-
sink(a, 0, i)
117-
}
118-
return a
119-
}
120-
func sink(a []int, i int, length int) {
121-
for {
122-
// 左节点索引(从0开始,所以左节点为i*2+1)
123-
l := i*2 + 1
124-
// 有节点索引
125-
r := i*2 + 2
126-
// idx保存根、左、右三者之间较大值的索引
127-
idx := i
128-
// 存在左节点,左节点值较大,则取左节点
129-
if l < length && a[l] > a[idx] {
130-
idx = l
131-
}
132-
// 存在有节点,且值较大,取右节点
133-
if r < length && a[r] > a[idx] {
134-
idx = r
135-
}
136-
// 如果根节点较大,则不用下沉
137-
if idx == i {
138-
break
139-
}
140-
// 如果根节点较小,则交换值,并继续下沉
141-
swap(a, i, idx)
142-
// 继续下沉idx节点
143-
i = idx
144-
}
145-
}
146-
func swap(a []int, i, j int) {
147-
a[i], a[j] = a[j], a[i]
148-
}
92+
```Python
93+
def heap_adjust(A, start=0, end=None):
94+
if end is None:
95+
end = len(A)
96+
97+
while start is not None and start < end // 2:
98+
l, r = start * 2 + 1, start * 2 + 2
99+
swap = None
100+
101+
if A[l] > A[start]:
102+
swap = l
103+
if r < end and A[r] > A[start] and (swap is None or A[r] > A[l]):
104+
swap = r
105+
106+
if swap is not None:
107+
A[start], A[swap] = A[swap], A[start]
108+
109+
start = swap
110+
111+
return
149112

113+
def heapsort(A):
114+
115+
# construct max heap
116+
n = len(A)
117+
for i in range(n // 2 - 1, -1, -1):
118+
heap_adjust(A, i)
119+
120+
# sort
121+
for i in range(n - 1, 0, -1):
122+
A[0], A[i] = A[i], A[0]
123+
heap_adjust(A, end=i)
124+
125+
return A
126+
127+
# test
128+
if __name__ == '__main__':
129+
a = [7, 6, 8, 5, 2, 1, 3, 4, 0, 9, 10]
130+
print(a)
131+
print(heapsort(a))
150132
```
151133

152134
## 参考

0 commit comments

Comments
 (0)