排序算法(2)--插入排序
插入排序主要是简单插入排序和希尔排序两种!
简单插入排序
概念:
插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
算法实现过程:
(1)将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
(2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
算法复杂度:
时间复杂度----平均:O(n^2) | 最坏:O(n^2) | 最好:O(n)
空间复杂度----O(1)
稳定性----稳定
实例:
def insert_sort(ls):
pointer = len(ls)
for p in range(1, pointer):
for i in range(p, 0, -1):
if ls[i] < ls[i-1]:
ls[i], ls[i-1] = ls[i-1], ls[i]
else:
break
return ls
if __name__ == '__main__':
ls = [34, 23, 78, 35, 98, 68, 18, 88, 47, 51]
print(ls)
sort_ls = insert_sort(ls)
print(sort_ls)
希尔排序
概念:
希尔排序是插入排序的一种更高效的改进版本。基于插入排序的以下两点性质而提出改进方法的:
(1)插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
(2)但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;
基本思想:
先将整个待排序的序列分割成为若干子序列分别进行简单插入排序,待整个序列中的数据"基本有序"时,再对全体记录进行依次直接插入排序。
算法实现过程:
(1)选择一个增量序列(ti,tj,……,tk),其中 ti > tj, tk = 1,一般可以取序列长度1/3为初始增量,即ti=len(seq)/3,则tj=ti/3,依次对前一个增量乘1/3,直到增量减到1为止。
(2)按增量序列个数 k,对序列进行 k 趟排序;
(3)每趟排序,根据对应的增量 ti,tj......将待排序列分割成若干长度为 m 的子序列,分别对各子表进行简单插入排序。仅增量因子为 1 时,整个序列再做为一个整体进行简单插入排序,稍微调整个别元素的顺序即可。
算法复杂度:
时间复杂度----平均:O(n^1.3) | 最坏:O(n^2) | 最好:O(n)
空间复杂度----O(1)
稳定性----不稳定
实例:
def shellSort(arr):
import math
gap = 1
< len(arr)/3):
# 定义一个初始增量
gap = gap*3+1
while gap > 0:
for i in range(gap, len(arr)):
temp = arr[i]
# j就相当于0,1,2,3...(len(arr)-gap),每次for循环加1
j = i - gap
# 以下循环直到arr[j]元素都是小于arr[i]时结束,即简单插入排序过程。
while j >= 0 and arr[j] > temp:
arr[j] =
j -= gap
temp =
# 按当前增量进行排序后,将增量变为上一次的1/3
# floor()是向下取整函数,比如floor(1.7)=1
gap = math.floor(gap/3)
return arr
if __name__ == '__main__':
ls = [34, 23, 78, 35, 98, 68, 18, 88, 47, 51]
print(ls)
sort_ls = shellSort(ls)
print(sort_ls)