python 排序算法
链接:http://hujiaweibujidao.github.io/blog/2014/05/07/python-algorithms-sort/
1、冒泡法(直接交换元素)
1 def bubble_sort(a_list): 2 a_len = len(a_list)-1 3 while a_len > 0: 4 for i in range(a_len): 5 if a_list[i] >a_list[i+1]: 6 a_list[i],a_list[i+1] = a_list[i+1],a_list[i] 7 print(a_list) 8 a_len -=1 9 10 if __name__ == '__main__': 11 a_list=[220,40,30,190,50,180,70,60,110,100] 12 bubble_sort(a_list) 13 print('final: ') 14 print(a_list)
输出:
[40, 220, 30, 190, 50, 180, 70, 60, 110, 100]
[40, 30, 220, 190, 50, 180, 70, 60, 110, 100]
[40, 30, 190, 220, 50, 180, 70, 60, 110, 100]
[40, 30, 190, 50, 220, 180, 70, 60, 110, 100]
[40, 30, 190, 50, 180, 220, 70, 60, 110, 100]
[40, 30, 190, 50, 180, 70, 220, 60, 110, 100]
[40, 30, 190, 50, 180, 70, 60, 220, 110, 100]
[40, 30, 190, 50, 180, 70, 60, 110, 220, 100]
[40, 30, 190, 50, 180, 70, 60, 110, 100, 220]
[30, 40, 190, 50, 180, 70, 60, 110, 100, 220]
[30, 40, 50, 190, 180, 70, 60, 110, 100, 220]
[30, 40, 50, 180, 190, 70, 60, 110, 100, 220]
[30, 40, 50, 180, 70, 190, 60, 110, 100, 220]
[30, 40, 50, 180, 70, 60, 190, 110, 100, 220]
[30, 40, 50, 180, 70, 60, 110, 190, 100, 220]
[30, 40, 50, 180, 70, 60, 110, 100, 190, 220]
[30, 40, 50, 70, 180, 60, 110, 100, 190, 220]
[30, 40, 50, 70, 60, 180, 110, 100, 190, 220]
[30, 40, 50, 70, 60, 110, 180, 100, 190, 220]
[30, 40, 50, 70, 60, 110, 100, 180, 190, 220]
[30, 40, 50, 60, 70, 110, 100, 180, 190, 220]
[30, 40, 50, 60, 70, 100, 110, 180, 190, 220]
final:
[30, 40, 50, 60, 70, 100, 110, 180, 190, 220]
2、选择排序法(交换元素位置下表,选出最大后交换元素)
1 def selection_sort(a_list): 2 alen = len(a_list) 3 while alen >0: 4 postion = 0 5 for i in range(1,alen): 6 if a_list[i] >a_list[postion]: 7 postion = i #选择最大元素位置下标 8 a_list[postion],a_list[alen-1] = a_list[alen-1],a_list[postion] 9 print(a_list) 10 alen -= 1 11 12 if __name__ == '__main__': 13 a_list=[120,40,30,190,50,280,70,60,110,100] 14 selection_sort(a_list) 15 print('final: ') 16 print(a_list)
输出结果:
[120, 40, 30, 190, 50, 100, 70, 60, 110, 280]
[120, 40, 30, 110, 50, 100, 70, 60, 190, 280]
[60, 40, 30, 110, 50, 100, 70, 120, 190, 280]
[60, 40, 30, 70, 50, 100, 110, 120, 190, 280]
[60, 40, 30, 70, 50, 100, 110, 120, 190, 280]
[60, 40, 30, 50, 70, 100, 110, 120, 190, 280]
[50, 40, 30, 60, 70, 100, 110, 120, 190, 280]
[30, 40, 50, 60, 70, 100, 110, 120, 190, 280]
[30, 40, 50, 60, 70, 100, 110, 120, 190, 280]
[30, 40, 50, 60, 70, 100, 110, 120, 190, 280]
final:
[30, 40, 50, 60, 70, 100, 110, 120, 190, 280]
3、插入排序法 将数据插入到排好的序列中。稳定的排序方法。
1 def insert_sort(alist): 2 length = len(alist) 3 for index in range(1,length): 4 p = index 5 while p >0: 6 if alist[p] < alist[p-1]: 7 alist[p],alist[p-1] = alist[p-1],alist[p] 8 p -= 1 9 print(alist) 10 return alist 11 12 if __name__ == '__main__': 13 alist=[220,40,30,190,50,180,70,60,110,100] 14 insert_sort(alist) 15 print('final: ') 16 print(alist)
输出:
[40, 220, 30, 190, 50, 180, 70, 60, 110, 100] 220前插入40
[30, 40, 220, 190, 50, 180, 70, 60, 110, 100] 40,220 前插入30
[30, 40, 190, 220, 50, 180, 70, 60, 110, 100]
[30, 40, 50, 190, 220, 180, 70, 60, 110, 100]
[30, 40, 50, 180, 190, 220, 70, 60, 110, 100]
[30, 40, 50, 70, 180, 190, 220, 60, 110, 100]
[30, 40, 50, 60, 70, 180, 190, 220, 110, 100]
[30, 40, 50, 60, 70, 110, 180, 190, 220, 100]
[30, 40, 50, 60, 70, 100, 110, 180, 190, 220]
final:
[30, 40, 50, 60, 70, 100, 110, 180, 190, 220]
4、归并排序
1 def merge_sort(alist): 2 m = len(alist) 3 if m > 1: 4 mid = len(alist)//2 5 left = alist[:mid] 6 right = alist[mid:] 7 merge_sort(left) 8 merge_sort(right) 9 i=j=k = 0 #counter 10 while i < len(left) and j < len(right): 11 if left[i] < right[j]: 12 alist[k] = left[i] 13 i = i+1 14 else: 15 alist[k] = right[j] 16 j = j+1 17 k =k+1 18 while i <len(left): 19 alist[k] = left[i] 20 i = i+1 21 k = k+1 22 while j <len(right): 23 alist[k] = right[j] 24 j = j+1 25 k = k+1 26 print(alist) 27 return alist 28 if __name__ == '__main__': 29 alist =
[2,23,13,8,10,19,12,11,7]
print(merge_sort(alist))
30 print(merge_sort(alist))
输出:
[2, 23]
[8, 13]
[2, 8, 13, 23]
[10, 19]
[7, 11]
[7, 11, 12]
[7, 10, 11, 12, 19]
[2, 7, 8, 10, 11, 12, 13, 19, 23]
[2, 7, 8, 10, 11, 12, 13, 19, 23]
5、快速排序
找枢轴位置,把数据分为两部分,左边小,右边大。然后两部分递归使用此类方法。
链接http://www.jb51.net/article/64645.htm
Pythonic实现 使用了Python中的 列表解析 (List Comprehension,也叫列表展开、列表推导),每一次 递归排序 都会产生新的列表,因此失去了快速排序算法本来的 原位排序 的优点。
1 def pycQuicksort(L): 2 if len(L) <= 1: return L 3 return pycQuicksort([x for x in L if x < L[0]]) + [x for x in L if x ==L[0]] + pycQuicksort([x for x in L if x > L[0]]) 4
标准实现
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 def stdQuicksort(L): 4 qsort(L, 0, len(L) - 1) 5 def qsort(L, first, last): 6 if first < last: 7 split = partition(L, first, last) 8 qsort(L, first, split - 1) 9 qsort(L, split + 1, last) 10 def partition(L, first, last): 11 # 选取列表中的第一个元素作为划分元素 12 pivot = L[first] 13 leftmark = first + 1 14 rightmark = last 15 while True: 16 while L[leftmark] <= pivot: 17 # 如果列表中存在与划分元素pivot相等的元素,让它位于left部分 18 # 以下检测用于划分元素pivot是列表中的最大元素时, 19 #防止leftmark越界 20 if leftmark == rightmark: 21 break 22 leftmark += 1 23 while L[rightmark] > pivot: 24 # 这里不需要检测,划分元素pivot是列表中的最小元素时, 25 # rightmark会自动停在first处 26 rightmark -= 1 27 if leftmark < rightmark: 28 # 此时,leftmark处的元素大于pivot, 29 #而rightmark处的元素小于等于pivot,交换二者 30 L[leftmark], L[rightmark] = L[rightmark], L[leftmark] 31 else: 32 break 33 # 交换first处的划分元素与rightmark处的元素 34 L[first], L[rightmark] = L[rightmark], L[first] 35 # 返回划分元素pivot的最终位置 36 return rightmark
另一种实现方式 left为暂存数据的位置
1 def quick_sort(alist,left,right): 2 if left >= right: 3 return alist 4 key = alist[left] #记录轴枢元素 5 low = left 6 high = right 7 while left <right: 8 while left < right and alist[right] >= key: 9 right -= 1 10 alist[left] = alist[right] #小值放在左侧 11 while left <right and alist[left] <= key: 12 left += 1 13 alist[right] = alist[left] #大值放在右侧 14 alist[right] = key #right指针位置为轴枢的正确位置 15 quick_sort(alist,low,left-1) 16 quick_sort(alist,left+1,high) 17 return alist 18 19 alist=[20,40,30,90,50,80,70,60,110,100] 20 print(quick_sort(alist,0,len(alist)-1))
6、希尔排序
先分组,再插入排序
1 def shell_sort(list): 2 n = len(list) 3 # 初始步长 4 gap = n // 2 5 while gap > 0: 6 for i in range(gap, n): 7 # 每个步长进行插入排序 8 temp = list[i] 9 j = i 10 # 插入排序 11 while j >= gap and list[j - gap] > temp: 12 list[j] = list[j - gap] 13 j -= gap 14 list[j] = temp 15 # 得到新的步长 16 gap = gap // 2 17 return list 18 19 20 L=[20,40,30,90,50,80,70,60,110,100] 21 print(shell_sort(L))