Skip to content

Commit 026ee6f

Browse files
committed
归并排序
1 parent 8b4b38d commit 026ee6f

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

merge_sort.md

+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#问题
2+
3+
归并排序
4+
5+
#思路说明
6+
7+
归并操作过程:
8+
9+
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
10+
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
11+
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
12+
4. 重复步骤3直到某一指针达到序列尾
13+
5. 将另一序列剩下的所有元素直接复制到合并序列尾
14+
15+
上述说法是理论表述,下面用一个实际例子说明:
16+
17+
例如一个无序数组[6,2,3,1,7]
18+
19+
首先将这个数组通过递归方式进行分解,直到:[6],[2],[3],[1],[7]
20+
21+
然后开始合并排序,也是用递归的方式进行:
22+
23+
1. 两个两个合并排序,得到:[2,6],[1,3],[7]
24+
2. 上一步中,其实也是按照本步骤的方式合并的,只不过由于每个list中一个数,不能完全显示过程。下面则可以完全显示过程。
25+
26+
初始:
27+
a = [2,6]
28+
b = [1,3]
29+
c = []
30+
第1步,顺序从a,b中取出一个数字:2,1
31+
比较大小后放入c中,并将该数字从原list中删除,结果是:
32+
a = [2,6]
33+
b = [3]
34+
c = [1]
35+
第2步,继续从a,b中按照顺序取出数字,也就是重复上面步骤,这次是:2,3
36+
比较大小后放入c中,并将该数字从原list中删除,结果是:
37+
a = [6]
38+
b = [3]
39+
c = [1,2]
40+
第3步,再重复前边的步骤,结果是:
41+
a = [6]
42+
b = []
43+
c = [1,2,3]
44+
最后一步,将6追加到c中,结果形成了:
45+
a = []
46+
b = []
47+
c = [1,2,3,6]
48+
49+
3. 通过反复应用上面的流程,实现[1,2,3,6][7]的合并
50+
4. 最终得到排序结果[1,2,3,6,7]
51+
52+
本文列举了三种python的实现方法。
53+
54+
#解决(Python)
55+
56+
#! /usr/bin/env python
57+
#coding:utf-8
58+
59+
#方法1:将前面讲述的过程翻译过来了,略先拙笨
60+
61+
def merge_sort(seq):
62+
if len(seq) ==1:
63+
return seq
64+
else:
65+
middle = len(seq)/2
66+
left = merge_sort(seq[:middle])
67+
right = merge_sort(seq[middle:])
68+
69+
i = 0 #left 计数
70+
j = 0 #right 计数
71+
k = 0 #总计数
72+
73+
while i < len(left) and j < len(right):
74+
if left[i] < right [j]:
75+
seq[k] = left[i]
76+
i +=1
77+
k +=1
78+
else:
79+
seq[k] = right[j]
80+
j +=1
81+
k +=1
82+
83+
remain = left if i<j else right
84+
r = i if remain ==left else j
85+
86+
while r<len(remain):
87+
seq[k] = remain[r]
88+
r +=1
89+
k +=1
90+
91+
return seq
92+
93+
#方法2:在按照顺序取数值方面,应用了list.pop()方法,代码更紧凑简洁
94+
#此方法来[自维基百科:归并操作](http://zh.wikipedia.org/zh/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F)
95+
96+
def merge_sort(lst): #此方法来自维基百科:http://zh.wikipedia.org/zh/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
97+
if len(lst) <= 1:
98+
return lst
99+
100+
def merge(left, right):
101+
merged = []
102+
103+
while left and right:
104+
merged.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
105+
106+
while left:
107+
merged.append(left.pop(0))
108+
109+
while right:
110+
merged.append(right.pop(0))
111+
112+
return merged
113+
114+
middle = int(len(lst) / 2)
115+
left = merge_sort(lst[:middle])
116+
right = merge_sort(lst[middle:])
117+
return merge(left, right)
118+
119+
#方法3:原来在python的模块heapq中就提供了归并排序的方法,只要将分解后的结果导入该方法即可
120+
#强大。
121+
#以下方法来自[resettacode](http://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#Python),并稍作修改
122+
123+
from heapq import merge
124+
125+
def merge_sort(seq):
126+
if len(seq) <= 1:
127+
return m
128+
else:
129+
middle = len(seq)/2
130+
left = merge_sort(seq[:middle])
131+
right = merge_sort(seq[middle:])
132+
return list(merge(left, right)) #heapq.merge()
133+
134+
if __name__=="__main__":
135+
seq = [1,3,6,2,4]
136+
print merge_sort(seq)

merge_sort.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#! /usr/bin/env python
2+
#coding:utf-8
3+
"""
4+
#solve 1
5+
6+
def merge_sort(seq):
7+
if len(seq) ==1:
8+
return seq
9+
else:
10+
middle = len(seq)/2
11+
left = merge_sort(seq[:middle])
12+
right = merge_sort(seq[middle:])
13+
14+
i = 0 #left 计数
15+
j = 0 #right 计数
16+
k = 0 #总计数
17+
18+
while i < len(left) and j < len(right):
19+
if left[i] < right [j]:
20+
seq[k] = left[i]
21+
i +=1
22+
k +=1
23+
else:
24+
seq[k] = right[j]
25+
j +=1
26+
k +=1
27+
28+
remain = left if i<j else right
29+
r = i if remain ==left else j
30+
31+
while r<len(remain):
32+
seq[k] = remain[r]
33+
r +=1
34+
k +=1
35+
36+
return seq
37+
38+
#solve 2
39+
40+
def merge_sort(lst): #此方法来自维基百科:http://zh.wikipedia.org/zh/%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F
41+
if len(lst) <= 1:
42+
return lst
43+
44+
def merge(left, right):
45+
merged = []
46+
47+
while left and right:
48+
merged.append(left.pop(0) if left[0] <= right[0] else right.pop(0))
49+
50+
while left:
51+
merged.append(left.pop(0))
52+
53+
while right:
54+
merged.append(right.pop(0))
55+
56+
return merged
57+
58+
middle = int(len(lst) / 2)
59+
left = merge_sort(lst[:middle])
60+
right = merge_sort(lst[middle:])
61+
return merge(left, right)
62+
"""
63+
#solve 3
64+
#以下方法来自:http://rosettacode.org/wiki/Sorting_algorithms/Merge_sort#Python
65+
#稍作修改
66+
67+
from heapq import merge
68+
69+
def merge_sort(seq):
70+
if len(seq) <= 1:
71+
return seq
72+
else:
73+
middle = len(seq)/2
74+
left = merge_sort(seq[:middle])
75+
right = merge_sort(seq[middle:])
76+
return list(merge(left,right))
77+
78+
if __name__=="__main__":
79+
seq = [1,3,6,2,4]
80+
print merge_sort(seq)

0 commit comments

Comments
 (0)