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

 

posted @ 2016-08-13 10:48  hb91  阅读(235)  评论(0编辑  收藏  举报