参考:
基本排序算法
面试必备 | 排序算法的Python实现
基本排序算法
冒泡排序
def bubble_sort(seq):
n = len(seq)
for i in range(n-1):
for j in range(n-1-i):
if seq[j] > seq[j+1]:
seq[j], seq[j+1] = seq[j+1], seq[j]
每次都从第一个元素开始,每次排好当前最大的元素。
选择排序
def select_sort(seq):
n = len(seq)
for i in range(n-1):
min_idx = i
for j in range(i+1, n):
if seq[j] < seq[min_idx]:
min_idx = j
if min_idx != i:
seq[i], seq[min_idx] = seq[min_idx], seq[i]
每次选择出最小的元素。
插入排序
def insertion_sort(seq):
n = len(seq)
for i in range(1, n):
value = seq[i]
pos = i
while pos > 0 and value < seq[pos-1]:
seq[pos] = seq[pos-1]
pos-=1
seq[pos] = value
注意:范围是到n。
高级排序算法
分治法:递归。分解,解决,合并。
归并排序
归并排序把数组递归成只有单个元素的数组,之后再不断两两 合并,最后得到一个有序数组。这里的递归基本条件就是只包含一个元素的数组,当数组只包含一个元素的时候,我们可以认为它本来就是有序的(当然空数组也不用排序)。
def merge_sort(seq):
if len(seq) <= 1: #只有一个元素时是递归出口
return seq
else:
mid = int(len(seq)/2)
left_half = merge_sort(seq[:mid])
right_half = merge_sort(seq[mid:])
# 合并两个有序的数组
new_seq = merge_sorted_list(left_half, right_half)
return new_seq
def merge_sorted_list(sorted_a, sorted_b):
length_a, length_b = len(sorted_a), len(sorted_b)
a = b = 0
new_sorted_list = list()
while a < length_a and b < length_b:
if sorted_a[a] < sorted_b[b]
new_sorted_list.append(sorted_a[a])
a += 1
else:
new_sorted_list.append(sorted_b[b])
b += 1
# 将剩下多余的放入有序数组
while a < length_a:
new_sorted_list.append(sorted_a[a])
a += 1
while b < length_b:
new_sorted_list.append(sorted_b[b])
b += 1
return new_sorted_list
快速排序
1.从序列当中选择一个基准数(pivot),简单起见可以选择第一个;
2.将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧;
3.重复步骤1.2,直到所有子集当中只有一个元素为止;
设第0个位置为pivot,设置首尾俩个指针 left, right,两个指针不断向中间收拢。如果遇到 left 位置的元素大于 pivot 并且 right 指向的元素小于 pivot,我们就交换这俩元素,当 left > right 的时候退出就行了,这样实现了一次遍历就完成了 partition。
def quicksort_inplace(array, beg, end): # 注意这里我们都用左闭右开区间,end 传入 len(array)
if beg < end: # beg == end 的时候递归出口
pivot = partition(array, beg, end)
quicksort_inplace(array, beg, pivot)
quicksort_inplace(array, pivot+1, end)
def partition(array, beg, end):
pivot_index = beg
pivot = array[pivot_index]
left = pivot_index + 1
right = end - 1 #开区间,最后一个元素位置是end-1 [0, end-1] or [0: end),括号表示开区间
while True:
while left <= right and array[left] < pivot:
left += 1
while right >= left and array[right] >= pivot:
right -= 1
if left > right:
break
else:
array[left], array[right] = array[right], array[left]
array[pivot_index], array[right] = array[right], array[pivot_index]
return right
def quicksort(lists,left,right):
if left >= right:
return lists
key = lists[left]
low = left
high = right
while left < right:
while left < right and lists[right] >= key:
right -= 1
lists[left] = lists[right]
while left < right and lists[left] <= key:
left += 1
lists[right] = lists[left]
lists[right] = key
quicksort(lists,low,left-1)
quicksort(lists,left+1,high)
return lists