问题
用Insert Sort对长度为n n n 的无序序列s s s 从小到大(升序)排序。
解法
将长度为n n n 的序列s = [ x 0 , x 1 , … , x n − 1 ] s = [x_0, x_1, \dots, x_{n-1}] s = [ x 0 , x 1 , … , x n − 1 ] 分为左右两个部分,已排序的l e f t = [ x 0 , … , x k ] left = [x_0, \dots, x_k] l e f t = [ x 0 , … , x k ] 和未排序的r i g h t = [ x k + 1 , … , x n − 1 ] right = [x_{k+1}, \dots, x_{n-1}] r i g h t = [ x k + 1 , … , x n − 1 ] ,其中0 ≤ k ≤ n 0 \le k \le n 0 ≤ k ≤ n 。如图:
初始时l e f t = ∅ , r i g h t = [ x 0 , … , x n − 1 ] left = \varnothing, right = [x_0, \dots, x_{n-1}] l e f t = ∅ , r i g h t = [ x 0 , … , x n − 1 ] 。
对l e f t left l e f t 和r i g h t right r i g h t 进行如下操作:
Copy function Insert(s, k, n):
let x = s[k+1]
for i = [0, k+1]
if i = 0 and x <= s[i]
break
if i > 0 and s[i-1] <= x <= s[i]
break
if i <= k
move s[i...k] to s[i+1...k+1]
let s[i] = x
(1) Insert函数第3-7行:遍历l e f t left l e f t 找出一个适合x x x 插入的位置s [ i ] s[i] s [ i ] 。其中i = 0 i = 0 i = 0 属于边界条件,只需判断x < = s [ 0 ] x <= s[0] x <= s [ 0 ] 即可;
(2) Insert函数第8-10行:若找到一个合适的插入位置0 < = i < = k 0 <= i <= k 0 <= i <= k 则将其插入;若找不到(i = k + 1 i = k + 1 i = k + 1 )则说明x x x 比l e f t left l e f t 中所有元素都大,不需要移动。下次调用Insert函数时输入参数k k k 变成k + 1 k + 1 k + 1 ,就可以将现在的s [ k + 1 ] s[k+1] s [ k + 1 ] 加入l e f t left l e f t 中;
上述操作如图:
运行一次Insert函数可以将r i g h t right r i g h t 最左边的元素插入到l e f t left l e f t 中合适的位置(l e f t left l e f t 长度减1,r i g h t right r i g h t 长度加1)。初始时l e f t left l e f t 长度为0 0 0 ,r i g h t right r i g h t 长度为n n n ,只需重复调用n n n 次Insert函数即可完成排序:
Copy function InsertSort(s, n):
for k = [0, n-2]
Insert(s, k, n)
例如下图中,l e f t left l e f t 部分为s [ 0 , 5 ] s[0,5] s [ 0 , 5 ] ,r i g h t right r i g h t 部分为s [ 6 , n − 1 ] s[6,n-1] s [ 6 , n − 1 ] ,r i g h t right r i g h t 最左边的首部元素x = s [ 6 ] = 41 x = s[6] = 41 x = s [ 6 ] = 41 ,在l e f t left l e f t 部分中合适的插入位置为i = 3 i = 3 i = 3 (s [ 2 ] ≤ x ≤ s [ 3 ] s[2] \le x \le s[3] s [ 2 ] ≤ x ≤ s [ 3 ] )。
将s [ 3 , 5 ] s[3,5] s [ 3 , 5 ] 向右移动一位到s [ 4 , 6 ] s[4,6] s [ 4 , 6 ] ,将原x x x 移动到s [ 3 ] s[3] s [ 3 ] ,就完成了一次插入。
复杂度
与BubbleSort算法类似,该算法的时间复杂度为O ( n 2 ) O(n^2) O ( n 2 ) ,空间复杂度为O ( 1 ) O(1) O ( 1 ) 。
源码
InsertSort.h
InsertSort.cpp
测试
InsertSortTest.cpp