算法导论-第二章

打算重温《算法导论》,然后把书中的伪代码努力变成Python代码,其实看MIT《算法导论》的公开课更有意思。

画外音:其实是当年没好好去上课…现在从头开始补-_-||

心诚则灵

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
                   _ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 永无BUG

插入排序

原书P26,中文版P14:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def insertion_sort(seq):
length = len(seq)
counter = 1
while counter < length:
key = seq[counter]
former = counter - 1
while former > -1 and seq[former] > key:
seq[former+1] = seq[former]
former -= 1
seq[former+1] = key
counter += 1

sequence = [5, 2, 4, 6, 1, 3]
insertion_sort(sequence)
print(sequence)

选择排序

在习题2.2-2中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def selection_sort(seq):
for num_counter, num_temp in enumerate(seq):
min_number = num_temp
min_pos = num_counter
for min_counter, min_temp in enumerate(seq[num_counter+1:]):
if min_number > min_temp:
min_number = min_temp
min_pos = min_counter + num_counter + 1
seq[num_counter], seq[min_pos] = seq[min_pos], seq[num_counter]

sequence = [5, 2, 4, 6, 1, 3]
selection_sort(sequence)
print(sequence)

归并排序

原书P31,中文版P19:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def merge_sort(seq):
length = len(seq)
if length < 2:
return seq
mid = length // 2
s1 = merge_sort(seq[:mid])
s2 = merge_sort(seq[mid:])
templ = []
i, j = 0, 0
while i < len(s1) and j < len(s2):
if s1[i] < s2[j]:
templ.append(s1[i])
i += 1
else:
templ.append(s2[j])
j += 1
templ += s1[i:]
templ += s2[j:]
return templ

sequence = [5, 2, 4, 6, 1, 3]
print(merge_sort(sequence))

最大子数组

原书P68,中文版P38

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
def enumerate_reversed(sequence, start=None):
n = len(sequence)-1 if start is None else start
for elem in reversed(sequence):
yield n, elem
n -= 1

def find_max_crossing_subarray(array, mid):
left_max, left_pos, left_sum = array[mid-1], mid-1, 0
for left_elem_idx, left_elem in enumerate_reversed(array[:mid]):
left_sum += left_elem
if left_sum > left_max:
left_pos = left_elem_idx
right_max, right_pos, right_sum = array[mid], mid, 0
for right_elem_idx, right_elem in enumerate(array[mid:]):
right_sum += right_elem
if right_sum > right_max:
right_pos = right_elem_idx
return array[left_pos:mid+right_pos+1]

def find_maximum_subarray(array):
if len(array) == 1:
return array
else:
mid = len(array) // 2
left_array = find_maximum_subarray(array[:mid])
right_array = find_maximum_subarray(array[mid:])
cross_array = find_max_crossing_subarray(array, mid)

left_sum, right_sum, cross_sum = sum(left_array), sum(right_array), sum(cross_array)
if left_sum > right_sum and left_sum > cross_sum:
return left_array
elif right_sum > left_sum and right_sum > cross_sum:
return right_array
return cross_array

test_array = [13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7]
maximum_array = find_maximum_subarray(test_array)
print(maximum_array)

注:应该避免在Python代码中,修改处于迭代中的容器,我这么写只是想高度还原伪代码而已╮(╯_╰)╭。

-EOF-

评论

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×