排序
冒泡排序O(n^2) 选择排序O(n^2) 插入排序O(n^2) 希尔排序O(n)-O(n^2) 归并排序O(nlogn) 快速排序O(nlogn)-O(n^2)
1、冒泡排序
1.1、常规
def bubbleSort ( alist) :
for epoch in range ( len ( alist) - 1 , 0 , - 1 ) :
for i in range ( epoch) :
if alist[ i] > alist[ i+ 1 ] :
alist[ i] , alist[ i+ 1 ] = alist[ i+ 1 ] , alist[ i]
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 78 , 99 , 9 , 7 ]
bubbleSort( alist)
alist
[1, 2, 7, 9, 16, 25, 25, 45, 78, 99]
1.2、短冒泡
def shortBubbleSort ( alist) :
exchanges = True
passnum = len ( alist- 1 )
while passnum > 0 and exchanges:
exchanges = False
for i in range ( passnum) :
if alist[ i] > alist[ i+ 1 ] :
exchanges = True
alist[ i] , alist[ i+ 1 ] = alist[ i+ 1 ] , alist[ i]
passnum -= 1
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 78 , 99 , 9 , 7 ]
bubbleSort( alist)
alist
[1, 2, 7, 9, 16, 25, 25, 45, 78, 99]
2、选择排序
def selectionSort ( alist) :
for epoch in range ( len ( alist) - 1 , 0 , - 1 ) :
positionOfMax = 0
for i in range ( 1 , 1 + epoch) :
if alist[ positionOfMax] < alist[ i] :
positionOfMax = i
alist[ positionOfMax] , alist[ epoch] = alist[ epoch] , alist[ positionOfMax]
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 10 , 78 , 99 , 9 , 7 ]
selectionSort( alist)
alist
[1, 2, 7, 9, 10, 16, 25, 25, 45, 78, 99]
3、插入排序
插入排序式中保持在列表的低位是已经排序的子列表,然后后面的项逐个插入到其中。
def insertionSort ( alist) :
for index in range ( 1 , len ( alist) ) :
currentvalue = alist[ index]
position = index
while position > 0 and alist[ position- 1 ] > currentvalue:
alist[ position] = alist[ position- 1 ]
position -= 1
alist[ position] = currentvalue
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 10 , 78 , 99 , 9 , 7 ]
insertionSort( alist)
alist
[1, 2, 7, 9, 10, 16, 25, 25, 45, 78, 99]
4、希尔排序
希尔排序是一种不稳定的排序法,即如果列表中有两个相同的值,则它俩的相对位置有可能发生改变
def shellSort ( alist) :
sublistcount = len ( alist) // 2
while sublistcount > 0 :
for startposition in range ( sublistcount) :
gapInsertionSort( alist, startposition, sublistcount)
print ( "增量为{},排序后为{}" . format ( sublistcount, alist) )
sublistcount = sublistcount // 2
def gapInsertionSort ( alist, start, gap) :
for i in range ( start + gap, len ( alist) , gap) :
currentvalue = alist[ i]
position = i
while position >= gap and alist[ position - gap] > currentvalue:
alist[ position] = alist[ position - gap]
position = position - gap
alist[ position] = currentvalue
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 10 , 78 , 99 , 9 , 7 , 19 ]
shellSort( alist)
alist
增量为6,排序后为[10, 1, 2, 9, 7, 16, 25, 78, 99, 45, 25, 19]
增量为3,排序后为[9, 1, 2, 10, 7, 16, 25, 25, 19, 45, 78, 99]
增量为1,排序后为[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]
[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]
5、归并排序
使用分而治之的策略,会使用额外的存储空间 是一种稳定的排序
def mergeSort ( alist) :
print ( "分割:" , alist)
if len ( alist) > 1 :
mid = len ( alist) // 2
lefthalf = alist[ : mid]
righthalf = alist[ mid: ]
mergeSort( lefthalf)
print ( "=============================" )
mergeSort( righthalf)
i, j , k = 0 , 0 , 0
while i < len ( lefthalf) and j < len ( righthalf) :
if lefthalf[ i] < righthalf[ j] :
alist[ k] = lefthalf[ i]
i += 1
else :
alist[ k] = righthalf[ j]
j += 1
k += 1
while i < len ( lefthalf) :
alist[ k] = lefthalf[ i]
i += 1
k += 1
while j < len ( righthalf) :
alist[ k] = righthalf[ j]
j += 1
k += 1
print ( "合并: " , alist)
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 10 , 78 , 99 , 9 , 7 , 19 ]
mergeSort( alist)
分割: [25, 1, 2, 45, 25, 16, 10, 78, 99, 9, 7, 19]
分割: [25, 1, 2, 45, 25, 16]
分割: [25, 1, 2]
分割: [25]
合并: [25]
=============================
分割: [1, 2]
分割: [1]
合并: [1]
=============================
分割: [2]
合并: [2]
合并: [1, 2]
合并: [1, 2, 25]
=============================
分割: [45, 25, 16]
分割: [45]
合并: [45]
=============================
分割: [25, 16]
分割: [25]
合并: [25]
=============================
分割: [16]
合并: [16]
合并: [16, 25]
合并: [16, 25, 45]
合并: [1, 2, 16, 25, 25, 45]
=============================
分割: [10, 78, 99, 9, 7, 19]
分割: [10, 78, 99]
分割: [10]
合并: [10]
=============================
分割: [78, 99]
分割: [78]
合并: [78]
=============================
分割: [99]
合并: [99]
合并: [78, 99]
合并: [10, 78, 99]
=============================
分割: [9, 7, 19]
分割: [9]
合并: [9]
=============================
分割: [7, 19]
分割: [7]
合并: [7]
=============================
分割: [19]
合并: [19]
合并: [7, 19]
合并: [7, 9, 19]
合并: [7, 9, 10, 19, 78, 99]
合并: [1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 78, 99]
另一种写法
def merge ( a, b) :
c = [ ]
h = j = 0
while j < len ( a) and h < len ( b) :
if a[ j] < b[ h] :
c. append( a[ j] )
j += 1
else :
c. append( b[ h] )
h += 1
if j == len ( a) :
for i in b[ h: ] :
c. append( i)
else :
for i in a[ j: ] :
c. append( i)
return c
def merge_sort ( lists) :
if len ( lists) <= 1 :
return lists
middle = len ( lists) // 2
left = merge_sort( lists[ : middle] )
right = merge_sort( lists[ middle: ] )
return merge( left, right)
if __name__ == '__main__' :
a = [ 14 , 2 , 34 , 43 , 21 , 19 ]
print ( merge_sort( a) )
[2, 14, 19, 21, 34, 43]
6、快速排序
def quickSort ( alist) :
quickSortHelper( alist, 0 , len ( alist) - 1 )
def quickSortHelper ( alist, first, last) :
if first < last:
splitpoint = partition( alist, first, last)
quickSortHelper( alist, first, splitpoint - 1 )
quickSortHelper( alist, splitpoint + 1 , last)
def partition ( alist, first, last) :
pivotvalue = alist[ first]
leftmark = first + 1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[ leftmark] <= pivotvalue:
leftmark = leftmark + 1
while rightmark >= leftmark and alist[ rightmark] >= pivotvalue:
rightmark = rightmark - 1
if rightmark < leftmark:
done = True
else :
alist[ leftmark] , alist[ rightmark] = alist[ rightmark] , alist[ leftmark]
alist[ first] , alist[ rightmark] = alist[ rightmark] , alist[ first]
return rightmark
alist = [ 25 , 1 , 2 , 45 , 25 , 16 , 60 , 10 , 78 , 99 , 9 , 7 , 19 ]
quickSort( alist)
alist
[1, 2, 7, 9, 10, 16, 19, 25, 25, 45, 60, 78, 99]