Thomas H.Cormen 的《算法导论》上介绍的几个经典排序算法的Python实现。
1、冒泡排序:
简单的两重循环遍历,使最小(最大)的值不断地往上升(下沉)而实现的排序,算法时间为O(n2)。
代码如下:
1 def up_sort(a):
2 # 冒泡排序
3
4 a_length = len(a)
5 while True:
6 i = 0
7 j = 1
8
9 while True:
10 if a[i] > a[j]:
11 a[i], a[j] = a[j], a[i]
12 i += 1
13 j = i+1
14 else:
15 i += 1
16 j = i+1
17 if j >= a_length:
18 break
19 a_length -= 1
20 if a_length == 1:
21 break
2、快速排序
快排是一种使用较多的一种排序算法,对于包含n个数输入数组,最坏情况运行时间为Θ(n2),期望运行时间为Θ(nlgn),而且常数因子较小,不容易出现最坏情况,所以快排常是进行排序的最佳选择。
其主要包括三个步骤(对子数组A[p...r]):
分解:数组A[p...r]被划分成两个子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的元素都小于等于A[q],而A[q+1..r]中的都大于A[q]
解决:通过递归调用快排,对数组A[p..q-1]和A[q+1..r]进行排序
合并:因为两个子数组是就地排序的,将他们的合并不需要操作:整个数组A[p..r]已排序
代码如下:
为排序一个完整的数组A,需调用quicksort(A,0,len[A]-1),partition()函数就是对子数组进行就地重排.
def partition(a, p, r):
x = a[r]
i = p-1
for j in range(p, r-1):
if a[j] <= x:
i += 1
a[i], a[j] = a[j], a[i]
a[i+1], a[r] = a[r], a[i+1]
return i+1
def quicksort(a, p, r):
'快排'
if p < r:
q = partition(a, p, r)
quicksort(a, p, q-1)
quicksort(a, q+1, r)
# print a
3、归并排序
归并排序是利用的分治的思想,讲一个要解决的问题划分为多个子问题,分别对每个子问题进行求解,算法直观的操作如下:
分解:将n个元素分解成各含n/2个元素的子序列;
解决:用合并排序法对两个子序列递归的排序
合并:合并两个已排序的子序列得到排序结果
代码如下:
归并排序的时间复杂度为Θ(nlgn)
1 def merge_sort(a, p, r):
2 '归并排序'
3 if p < r:
4 q = (p+r)//2
5 merge_sort(a, p, q)
6 merge_sort(a, q+1, r)
7
8 merge(a, p, q, r)
9
10
11 def merge(a, p, q, r):
12 n1 = q - p + 1
13 n2 = r - q
14 left = []
15 right = []
16 for i1 in range(0, n1):
17 left.append(a[p+i1])
18 for j1 in range(0, n2):
19 right.append(a[q+j1+1])
20
21 left.append(float('inf'))
22 right.append(float('inf'))
23 i = 0
24 j = 0
25 for k in range(p, r+1):
26 if left[i] <= right[j]:
27 a[k] = left[i]
28 i += 1
29 else:
30 a[k] = right[j]
31 j += 1
4、完整代码:
包括实验的测试代码如下:
1 # -*- coding: utf-8 -*-
2
3 # !/usr/bin/env python
4
5
6 __author__ = 'you'
7
8 import random
9 import time
10
11
12 def up_sort(a):
13 # 冒泡排序
14
15 a_length = len(a)
16 while True:
17 i = 0
18 j = 1
19
20 while True:
21 if a[i] > a[j]:
22 a[i], a[j] = a[j], a[i]
23 i += 1
24 j = i+1
25 else:
26 i += 1
27 j = i+1
28 if j >= a_length:
29 break
30 a_length -= 1
31 if a_length == 1:
32 # print a
33 break
34
35
36 def partition(a, p, r):
37 x = a[r]
38 i = p-1
39 for j in range(p, r-1):
40 if a[j] <= x:
41
42 i += 1
43 a[i], a[j] = a[j], a[i]
44 a[i+1], a[r] = a[r], a[i+1]
45 return i+1
46
47
48 def quicksort(a, p, r):
49 '快排'
50 if p < r:
51 q = partition(a, p, r)
52 quicksort(a, p, q-1)
53 quicksort(a, q+1, r)
54 # print a
55
56
57 def merge(a, p, q, r):
58 n1 = q - p + 1
59 n2 = r - q
60 left = []
61 right = []
62 for i1 in range(0, n1):
63 left.append(a[p+i1])
64 for j1 in range(0, n2):
65 right.append(a[q+j1+1])
66
67 left.append(float('inf'))
68 right.append(float('inf'))
69 i = 0
70 j = 0
71 for k in range(p, r+1):
72 if left[i] <= right[j]:
73 a[k] = left[i]
74 i += 1
75 else:
76 a[k] = right[j]
77 j += 1
78
79
80 def merge_sort(a, p, r):
81 '归并排序'
82 if p < r:
83 q = (p+r)//2
84 merge_sort(a, p, q)
85 merge_sort(a, q+1, r)
86
87 merge(a, p, q, r)
88 # print a
89
90
91 if __name__ == '__main__':
92 in_len = int(raw_input('输入排序个数:'))
93 begin_num = int(raw_input('输入随机产生序列的范围:'))
94 end_num = int(raw_input())
95
96 A = []
97 for i in range(0, in_len):
98 A.append(random.randrange(begin_num, end_num))
99 # print(A)
100 while True:
101 print '-'*10+'算法性能比较'+'-'*10
102 print '''
103 1、冒泡排序
104 2、快排
105 3、归并排序
106 0、退出
107 '''
108 print '-'*30
109 select=int(raw_input('输入选择'))
110 if select == 1:
111 begin_time=time.time()
112
113
114 up_sort(A)
115 # print A
116 end_time=time.time()
117 elif select == 0:
118 break
119 elif select == 2:
120 begin_time=time.time()
121 quicksort(A, 0, len(A)-1)
122 end_time=time.time()
123 else:
124 begin_time=time.time()
125 merge_sort(A, 0, len(A)-1)
126 end_time=time.time()
127 print '该算法的耗时为:'+str((end_time-begin_time)*1000)+'ms'
完整代码