参考地址:https://www.runoob.com/w3cnote/bubble-sort.html
一、快速排序
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。
方法一
A = [16,4,6,3,77,22,10,6]
def quick_sort(A):
# print len(A)//2
if len(A) < 2:
return A
mid = A[len(A)//2]
left,right = [],[]
A.remove(mid)
for item in A:
if item < mid:
left.append(item)
else:
right.append(item)
# quick_sort(left)
# quick_sort(right)
return quick_sort(left) + [mid] + quick_sort(right)
if __name__ == "__main__":
result = quick_sort(A)
print result
方法二
def partition(arr,low,high):
i = ( low-1 ) # 最小元素索引
pivot = arr[high]
for j in range(low , high):
# 当前元素小于或等于 pivot
if arr[j] <= pivot:
i = i+1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
# arr[] --> 排序数组
# low --> 起始索引
# high --> 结束索引
# 快速排序函数
def quickSort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr,0,n-1)
print ("排序后的数组:")
for i in range(n):
print ("%d" %arr[i]),
二、冒泡排序
算法步骤:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
冒泡排序有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。
def sort():
a = [1,4,6,3,77,22,10]
for i in range(0,len(a)):
for j in range(0,len(a)-i-1):
if a[j] > a[j+1]:
a[j],a[j+1] = a[j+1],a[j]
print a
if __name__ == "__main__":
sort()
冒泡排序优化:
def sort():
a = [1,4,6,3,77,22,10]
for i in range(0,len(a)):
flag = True
for j in range(0,len(a)-i-1):
if a[j] > a[j+1]:
a[j],a[j+1] = a[j+1],a[j]
flag = False
if flag:
return a
print a
return a
if __name__ == "__main__":
sort()
三、选择排序
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
算法步骤:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
def sort():
a = [16,4,6,3,77,22,10,6]
for i in range(len(a)-1):
min = i
for j in range(i+1,len(a)):
if a[min] > a[j]:
min = j
if min!=i:
a[min],a[i] = a[i],a[min]
return a
if __name__ == "__main__":
result = sort()
print result
四、插入排序
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
def insertionSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
五、归并排序
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。
2. 算法步骤
-
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
-
设定两个指针,最初位置分别为两个已经排序序列的起始位置;
-
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
-
重复步骤 3 直到某一指针达到序列尾;
-
将另一序列剩下的所有元素直接复制到合并序列尾。
def merge_sort(arr):
if len(arr)<2:
return arr
mid = len(arr)//2
left,right = arr[0:mid],arr[mid:]
return merge(merge_sort(left),merge_sort(right))
def merge(left,right):
res = []
while left and right:
if left[0] <= right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
while left:
res.append(left.pop(0))
while right:
res.append(right.pop(0))
return res
if __name__ == "__main__":
arr = [16, 4, 6, 3, 77, 22, 10, 6]
res = merge_sort(arr)
print res