用python实现各种排序(插入、冒泡、归并、堆、快排)。
1、插入排序:
进行N-1次插入,通过比较将key插入已经排好序的子数组。
1 #! /usr/bin/python
2 #_*_ coding:utf8
3 #the insert sort algorithm
4 #非降序
5 #O(N2)
6
7 import sys
8
9 def insert_sort(sourse):
10 i=1 #the cursor
11 for i in range(len(sourse)):
12 sourse[i]=int(sourse[i])
13 print "before:"
14 print sourse
15 for i in range(1,len(sourse)):
16 key=sourse[i]
17 j=i
18 #insert the key into sourse[0~i-1],which is sorted already
19 while sourse[j-1]>key and j>0:
20 sourse[j]=sourse[j-1]
21 j-=1
22 sourse[j]=key
23 print "after:"
24 print sourse
25 return
26
27 if __name__=='__main__':
28 sourse=sys.argv[1:]
29 insert_sort(sourse)
进行N-1轮冒泡排序,通过比较相邻的元素,每轮选出剩下中最小的数存在最左边。
1 #! /usr/bin/python
2 # _*_ coding: utf8
3 #冒泡排序,O(N2),稳定,代码简单
4
5 import sys
6
7 def buddleSort(A):
8 #进行len(A)-1次冒泡排序
9 for i in range(len(A)-1):
10 #每次冒泡排序都将最小的这轮中选出的最小的数排到这轮的最左端
11 for j in range(len(A)-1,i,-1):
12 if A[j-1]>A[j]:
13 A[j-1],A[j]=A[j],A[j-1]
14 return
15
16
17 if __name__=='__main__':
18 A=sys.argv[1:]
19 for i in range(len(A)):
20 A[i]=int(A[i])
21 buddleSort(A)
22 print A
3、归并排序:
分治法思想,排序A就是排序A1和A2并将A1和A2归并的过程,如此分解下去,最后子数组就只有一个元素,很容易解决排序(不用排了)。那么归并排序的复杂度都体现在归并的过程。采用递归的方式体现分治的过程。
1 #! /usr/bin/python
2 # _*_ coding: utf8
3 #归并排序过程,其中最重要的就是子过程:MERGE(合并过程)
4 #O(N*lgN)
5
6 import sys
7
8 #合并两个有序的子数组
9 def merge(A,p,q,r):
10 n1=q-p+1
11 n2=r-q
12 A1=[]
13 A2=[]
14 j=0
15 k=0
16 #注意添加在子数组的最后添加哨兵位,这样就不用检查哪个子数组匹配完了,简化了代码
17 for i in range(n1):
18 A1.append(A[p+i])
19 A1.append(sys.float_info.max)
20 for i in range(n2):
21 A2.append(A[q+i+1])
22 A2.append(sys.float_info.max)
23 for i in range(p,r+1):
24 if A1[j]<=A2[k]:
25 A[i]=A1[j]
26 j+=1
27 else:
28 A[i]=A2[k]
29 k+=1
30 return
31
32 #主程序,分治法
33 def merge_sort(A,p,r):
34 if p<r:
35 q=(p+r)/2
36 merge_sort(A,p,q)
37 merge_sort(A,q+1,r)
38 merge(A,p,q,r)
39 return
41 if __name__=='__main__':
42 A=sys.argv[1:]
43 for i in range(len(A)):
44 A[i]=int(A[i])
45 merge_sort(A,0,len(A)-1)
46 print A
4、堆排序:
采用最大堆结构,首先建立大根堆,将堆顶元素和最后一个元素交换并获取堆顶元素。然后将换过后的满二叉树调成为大根堆,继续上序过程。
1 #! /usr/bin/python
2 # _*_ coding: utf8
3 #堆派序,O(NlgN)
4
5 import sys
6
7 #主要的子过程,将A中以第i个节点为根的子树成为最大堆,前提是这个子树的左子树和右子树已经是大根堆了,i的范围是从1到len(A)。里面有个递归的过程,O(lgN)
8 def heap_MAX_i(A,i):
9 left=i*2
10 right=i*2+1
11 largest=i
12 if left<=len(A) and A[left-1]>A[i-1]:
13 largest=left
14 if right<=len(A) and A[right-1]>A[largest-1]:
15 largest=right
16 if largest<>i:
17 A[i-1],A[largest-1]=A[largest-1],A[i-1]
18 heap_MAX_i(A,largest)
19 return
20
21 #建立大根堆,O(N),从最后一个非叶子节点开始到根节点
22 def make_heap_MAX(A):
23 for i in range(len(A)/2,0,-1):
24 heap_MAX_i(A,i)
25
26 #堆排序O(N*lgN)
27 def heap_sort(A):
28 make_heap_MAX(A)#第一步,建立大根堆
29 outcome=[]
30 length=len(A)
31 for i in range(length,1,-1):
32 A[i-1],A[0]=A[0],A[i-1]
33 outcome.append(A.pop())#将堆顶和最后一个节点交换并获取这个堆顶元素
34 heap_MAX_i(A,1)
35 outcome.append(A[0])
36 print outcome
37
38 if __name__=='__main__':
39 A=sys.argv[1:]
40 for i in range(len(A)):
41 A[i]=int(A[i])
42 heap_sort(A)
5、快排:
分治法思想,这次主要过程不是归并了,而是分解的过程,A分解成A1和A2中的所有元素都小于中的任意元素,其中已经排好序。
1 #! /usr/bin/python
2 #_*_ coding: utf8
3 #快速排序,0(NlgN)
4
5 import sys
6
7 #数组就地划分
8 def partition(A,p,r):
9 x=A[r]
10 i=p-1
11 for j in range(p,r):
12 if A[j]<=x:
13 i+=1
14 A[i],A[j]=A[j],A[i]
15 A[i+1],A[r]=A[r],A[i+1]
16 return i+1
17
18 #快排,主要就是划分过程
19 def quick_sort(A,p,r):
20 if p<r:
21 q=partition(A,p,r)
22 quick_sort(A,p,q-1)
23 quick_sort(A,q+1,r)
24
25
26 if __name__=='__main__':
27 A=sys.argv[1:]
28 for i in range(len(A)):
29 A[i]=int(A[i])
30 quick_sort(A,0,len(A)-1)
31 print A