1 '''
2 Created on 2016/12/16
3 Created by freeol.cn
4 一些排序算法的Python实现
5 @author: 拽拽绅士
6 '''
7
8 '''值交换'''
9 def swap(m, n):
10 c = m; m = n; n = c;
11 return m, n
12
13 '''冒泡排序
14 特征:
15 稳定排序算法
16 最坏时间复杂度O(n^2)
17 平均时间复杂度O(n^2)
18 空间复杂度O(1)
19 总结:重复的相邻元素进行比较交换,越大的元素
20 会经由交换慢慢“浮”到数列的顶端'''
21 def bubbleSort(a):
22 for i in range(0, len(a)):
23 for j in range(0, len(a)-i-1):
24 if a[j] > a[j+1]:
25 a[j], a[j+1] = swap(a[j],a[j+1])
26 return a
27
28 '''选择排序
29 特征:
30 不稳定排序算法
31 最坏时间复杂度O(n^2)
32 平均时间复杂度O(n^2)
33 空间复杂度O(1)
34 总结:重复的选择后面最小的与遍历到的位置交换'''
35 def selectSort(a):
36 for i in range(0, len(a)-1):
37 min = i
38 for j in range(i+1, len(a)):
39 if a[j] < a[min]:
40 min = j
41 a[i], a[min] = swap(a[i], a[min])
42 return a
43
44 '''插入排序
45 特征:
46 稳定排序算法
47 最坏时间复杂度O(n^2)
48 平均时间复杂度O(n^2)
49 空间复杂度O(1)
50 总结:
51 重复的将遍历元素暂存后,将遍历元素之前的元素较暂存元素大的后移,
52 将暂存元素插入后移元素最小的前面弥补遍历之前元素后移覆盖引起的元素缺失'''
53 def insertSort(a):
54 for i in range(1, len(a)):
55 e=a[i]; j=i;
56 while j>0:
57 if a[j-1] > e:
58 a[j] = a[j-1]
59 else:
60 break
61 j-=1
62 a[j] = e
63 return a
64
65 '''归并排序
66 特征:
67 稳定排序算法
68 最坏时间复杂度O(nlogn)
69 平均时间复杂度O(nlogn)
70 空间复杂度O(n)
71 总结:
72 分治法(Divide and Conquer)的典型应用,
73 递归的将数组分成左右两部分数组,每次分完后将小的放在左边的数组,
74 大的放在右边的数组,分完后将左右两个数组归并成一个数组'''
75 class merge(object):
76 a = None
77 def __init__(self, a):
78 self.a = a
79
80 def __MergeSort(self, lst):
81 if len(lst) <= 1:
82 return lst
83 num = int(len(lst)/2)
84 left = self.__MergeSort(lst[:num])
85 right = self.__MergeSort(lst[num:])
86 return self.__Merge(left, right)
87
88 def __Merge(self, left, right):
89 R, L=0, 0
90 result=[]
91 while L < len(left) and R < len(right):
92 if left[L] < right[R]:
93 result.append(left[L])
94 L += 1
95 else:
96 result.append(right[R])
97 R += 1
98 result += right[R:]
99 result += left[L:]
100 return result
101
102 def sort(self):
103 return self.__MergeSort(self.a)
104
105 '''快速排序
106 特征:
107 不稳定排序算法
108 最坏时间复杂度O(n^2)
109 平均时间复杂度O(nlogn)
110 空间复杂度O(logn)~O(n)
111 注:初始最低位L输入为0, 最高位H输入为数组长度减1即数组末尾的索引值
112 总结:
113 引用分治法对冒泡法的改进,
114 递归的以数组最低位为基数,重复的左右两端相向与基数比较,
115 左边比基数大的与右边比基数小的交换,直到左右相遇,
116 这是一个将最低位元素移动到已排序后数组位置的过程'''
117 def quickSort(a, L, H):
118 i = L; j = H;
119 if i >= j:
120 return a
121 B = a[i]
122 while i < j:
123 while i < j and a[j] >= B:
124 j = j-1
125 a[i] = a[j]
126 while i < j and a[i] <= B:
127 i = i+1
128 a[j] = a[i]
129 a[i] = B
130 a = quickSort(a, L, i-1)
131 a = quickSort(a, j+1, H)
132 return a
133
134 '''统计排序
135 注:由于统计排序需要有已知有序数组做筒,故这里统计后
136 使用python自带的sort生成已知有序数组
137 总结:已知有序数组做筒,统计相同元素数量
138 '''
139 def countSort(a):
140 dtmp = {}
141 for i in a:
142 if i not in dtmp:
143 dtmp[i]=1
144 else:
145 dtmp[i]+=1
146 tmp = list(dtmp.keys())
147 tmp.sort()
148 a=[]
149 for i in tmp:
150 for j in range(dtmp[i]):
151 a.append(i)
152 dtmp = None
153 tmp = None
154 return a
155
156 '''基数排序
157 稳定排序算法
158 注:因为在这里以0-9分别做每位比较后存入的筒,这里输入的数组中应是整数'''
159 def radixSort(a):
160 max = 0
161 for i in a:
162 if i > max:
163 max = i
164 b = len(str(max))
165 for i in range(b):
166 tmp=[[], [], [], [], [], [], [], [], [], []]
167 for j in a:
168 v = str(j)
169 if len(v)-1 < i:
170 tmp[0].append(j)
171 else:
172 k = v[len(v)-i-1:len(v)-i]
173 tmp[int(k)].append(j)
174 index = 0
175 for t in tmp:
176 for tv in t:
177 a[index] = tv
178 index+=1
179 return a
180
181 def main():
182 r = [15,28,6,1,5,47,265,19, 8, 255, 166, 78, 41, 8, 16,
183 215,128,26,11,25,147,265,19, 28, 155, 266, 178, 1, 8, 160,
184 153,282,6,12,52,472,652,97, 87, 55, 66, 78, 14, 80, 16]
185 #r = ['c', 'v', 's', 'd', 'e', 'f', 'a', 'k', 'l']
186 print('未排序数组 长度=',len(r),'
', r)
187 a0 = r.copy()
188 a1 = r.copy()
189 a2 = r.copy()
190 a3 = r.copy()
191 a4 = r.copy()
192 a5 = r.copy()
193 a6 = r.copy()
194 r.sort()
195 print('python中list自带的排序
', r)
196 print('冒泡排序
', bubbleSort(a0))
197 print('选择排序
', selectSort(a1))
198 print('插入排序
', insertSort(a2))
199 print('归并排序
', merge(a3).sort())
200 print('快速排序
', quickSort(a4,0, len(a4)-1))
201 print('统计排序
', countSort(a5))
202 print('基数排序
', radixSort(a6))
203
204 if __name__ == '__main__':
205 main()