vlambda博客
学习文章列表

排序算法(2)--插入排序

     

        插入排序主要是简单插入排序和希尔排序两种!


简单插入排序


概念:

        插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。


算法实现过程:

(1)将待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

(2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

排序算法(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)但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位;


基本思想:

        先将整个待排序的序列分割成为若干子序列分别进行简单插入排序,待整个序列中的数据"基本有序"时,再对全体记录进行依次直接插入排序。

排序算法(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 while(gap < 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+gap] = arr[j] j -= gap arr[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)