十大经典排序算法之属性总览
1. 插入排序
从第二个元素开始和前面的元素进行比较(逆序比较),如果前面的元素比当前元素大,则将前面元素后移一位;当前元素继续往前比较,直到找到比它小或等于它的元素并插入在其后面;然后选择第三个元素,重复上述操作,进行插入,依次选择到最后一个元素,插入后即完成所有排序
def insertionSort ( arr) :
for i in range ( 1 , len ( arr) ) :
curr = arr[ i]
pre_idx = i - 1
while pre_idx >= 0 and arr[ pre_idx] >= curr:
arr[ pre_idx + 1 ] = arr[ pre_idx]
pre_idx -= 1
arr[ pre_idx + 1 ] = curr
return arr
2. 选择排序
设第一个元素为比较元素,依次和后面的元素比较,比较完所有元素找到最小的元素,将它和第一个元素互换,重复上述操作;找出第二小的元素和第二个位置的元素互换,以此类推找出剩余最小元素将它换到前面,即完成排序
def selectionSort ( arr) :
for i in range ( len ( arr) - 1 ) :
min_idx = i
for j in range ( i, len ( arr) ) :
if arr[ min_idx] > arr[ j] :
min_idx = j
arr[ min_idx] , arr[ i] = arr[ i] , arr[ min_idx]
return arr
3. 冒泡排序
从第一个和第二个开始比较,如果第一个比第二个大,则交换位置,然后比较第二个和第三个,逐渐往后,经过第一轮后最大的元素已经排在最后;重复上述操作的话第二大的则会排在倒数第二的位置;重复上述操作n-1次即可完成排序,因为最后一次只有一个元素所以不需要比较
def bubbleSort ( arr) :
for i in range ( len ( arr) - 1 ) :
for j in range ( len ( arr) - 1 - i) :
if arr[ j] > arr[ j+ 1 ] :
arr[ j] , arr[ j+ 1 ] = arr[ j+ 1 ] , arr[ j]
return arr
4. 快速排序
从原数组中随机选择一个值作为中枢值,数组中剩下的每一个元素与中枢值进行比较;小于中枢值的元素存放到一个子数组,大于中枢值的元素存放到另一个子数组,对子数组递归进行上述操作,直至子数组长度为0或1时返回子数组,开始返回递归
def quickSort ( arr) :
if len ( arr) < 2 :
return arr
pivot_idx = 0
pivot_idx = - 1
pivot_idx = len ( arr) // 2
pivot = arr[ pivot_idx]
arr. pop( pivot_idx)
L = [ i for i in arr if i <= pivot]
R = [ i for i in arr if i > pivot]
return quickSort( L) + [ pivot] + quickSort( R)
5. 归并排序
使用二分法将原数组不断两两划分,直至达到原子数组,然后返回递归;在返回过程中对子数组进行排序,再两两合并,直至合并到原数组长度(分而治之)
def mergeSort ( arr) :
if len ( arr) < 2 :
return arr
mid = len ( arr) // 2
L, R = mergeSort( arr[ : mid] ) , mergeSort( arr[ mid: ] )
sorted_arr = [ ]
while len ( L) > 0 and len ( R) > 0 :
if L[ 0 ] > R[ 0 ] :
sorted_arr. append( R. pop( 0 ) )
else :
sorted_arr. append( L. pop( 0 ) )
sorted_arr += L
sorted_arr += R
return sorted_arr
6. 堆排序
堆分为最大堆和最小堆,是完全二叉树;堆排序就是把堆顶的最大数取出,将剩余的堆继续调整为最大堆;剩余部分调整为最大堆后,再次将堆顶的最大数取出,再将剩余部分调整为最大堆,这个过程持续到剩余数只有一个时结束
def heapify_recur ( arr, p_idx, heap_size) :
max_idx = p_idx
l_idx, r_idx = p_idx * 2 + 1 , p_idx * 2 + 2
if l_idx < heap_size and arr[ max_idx] < arr[ l_idx] :
max_idx = l_idx
if r_idx < heap_size and arr[ max_idx] < arr[ r_idx] :
max_idx = r_idx
if max_idx != p_idx:
arr[ p_idx] , arr[ max_idx] = arr[ max_idx] , arr[ p_idx]
heapify_recur( arr, max_idx, heap_size)
def heapify ( arr, parent_idx, heap_size) :
parent_val = arr[ parent_idx]
child_idx = parent_idx * 2 + 1
while child_idx < heap_size:
if child_idx + 1 < heap_size and arr[ child_idx] < arr[ child_idx + 1 ] :
child_idx += 1
if parent_val >= arr[ child_idx] :
break
arr[ parent_idx] = arr[ child_idx]
parent_idx = child_idx
child_idx = parent_idx * 2 + 1
arr[ parent_idx] = parent_val
def heapSort ( arr) :
for parent_idx in range ( len ( arr) // 2 - 1 , - 1 , - 1 ) :
heapify( arr, parent_idx, len ( arr) )
for heap_size in range ( len ( arr) - 1 , 0 , - 1 ) :
arr[ 0 ] , arr[ heap_size] = arr[ heap_size] , arr[ 0 ]
heapify( arr, 0 , heap_size)
return arr