一些排序算法的Python实现

  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()