python 经典排序方法及优势比较
冒泡排序
冒泡排序思想:遍历整个数据列表,在一组数据中,每遍历比较一次数据,最大的数便会“冒泡”到数据列表右端
def bubble_sort(arr):
for i in range(len(arr)):
for j in range(len(arr)-i-1): # 最后的数自动排列到正确位置
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
选择排序
选择排序思想:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
每次找到最小的数据,然后于循环最左端放置
# 选择排序
def selection_sort(arr):
n = len(arr)
for i in range(n):
min_index = i
for j in range(i+1,n):
if arr[j]< arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
插入排序
插入排序思想:插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。其是遍历比较两个数据,然后递减数据下标,依次反复比较,直到排列好数据。
def insert_sort(arr):
for x in range(1,len(arr)):
while x > 0:
if arr[x] < arr[x-1]:
arr[x], arr[x-1] = arr[x-1], arr[x]
x -= 1
else:
break
return arr
希尔排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的版本,其是根据插入排序的性质进行优化的:
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
- 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
希尔排序基本思想:设置增量,将数据分为若干个小组,然后比较大小;然后增量递减,直到增量变为1,待数据列表形成有序列表。
def shell_sort(arr):
arr_length = len(arr)
n = arr_length
while n > 0:
n = n // 2 # 设置增量
for i in range(n):
for j in range(i, arr_length, n):
temp = arr[j]
if temp < arr[j-n]: # 比较数据
while temp < arr[j-n] and j > 0:
arr[j] = arr[j-n]
j -= n
arr[j] = temp
return arr
快速排序
快速排序是使用分治法(Divide and conquer)策略来吧一个串行分为两个字串行,然后进行递归运算,从本质上来说,快速排序应该算是在冒泡排序基础上的递归分治法。
def quick_sort(arr):
"""快速排序"""
if len(arr) < 2:
return arr
# 选取基准,随便选哪个都可以,选中间的便于理解
mid = arr[len(arr) // 2]
# 定义基准值左右两个数列
left, right = [], []
# 从原始数组中移除基准值
arr.remove(mid)
for item in arr:
# 大于基准值放右边
if item >= mid:
right.append(item)
else:
# 小于基准值放左边
left.append(item)
# 使用迭代进行比较
return quick_sort(left) + [mid] + quick_sort(right)
归并排序
**归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
# 归并排序
def mergeSort(arr):
import math
if len(arr) < 2:
return arr
middle = math.floor(len(arr)/2)
left, right = arr[0:middle], arr[middle:]
return merge(mergeSort(left), mergeSort(right))
def merge(left, right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return result