wuxiaosi0 2019-06-28
插入排序的原理是构建有序序列,对于给定的一个无序序列,从前往后遍历,在该元素之前的序列中从后往前扫描,寻找正确位置,这样对于每一个正在排序的元素,前面的序列总是有序的,当遍历完整个序列,即完成排序。《算法导论》给了一个更通俗更容易理解的形象的描述。我们都玩过扑克牌,大多数人拿扑克牌的时候都有这么个习惯,那就是将扑克牌按照一定的顺序排列好,而插入排序就好比你不断从桌上一堆无序排中拿起最上面的那张,然后放入自己手中已有的牌中,而每一次放的过程你都会按照某个顺序将这张新拿到的牌插入正确的位置,这样你手中的牌一直是有序的,而你抽取牌所在的牌堆是无序的。
下面以非降序排序为例:
key
,在前面已排序的有序序列中从后往前扫描;key
,将该元素移至下一个位置;key
的位置;key
插入到该位置;以斜体数字如 (1) 表示key
,以粗体数字如 ‘1’ 表示已排序序列,为了更直观,用中括号括起来,普通数字如‘1’表示未排序乱序序列,简要表示排序流程如下:
可以在这里看到插入排序的动态演示:
VisuAlgo-排序(冒泡排序,选择排序,插入排序,归并排序,快速排序,基数排序,基数排序)
(伪代码引用《算法导论》给出的例子)
INSERTION-SORT(A)
for j = 2 to A.length key = A[j] // Insert A[j] into the sorted sequence A[1..j - 1]. i = j - 1 while i > 0 and A[i] > key A[i + 1] = A[i] i = i - 1 A[i + 1] = key
为了更直观,我们将所有元素从1号元素开始计数,将0号元素视为无穷小,即数组长度为arrLength + 1
,序列存储于arr[1..arrLength]
。
void insertionSort(arrType* arr, int arrLength) { int i, j; arrType key; for (j = 2; j <= arrLength; j++) { key = arr[j]; i = j - 1; while (i > 0 && arr[i] > key) { arr[i + 1] = arr[i]; i--; } arr[i + 1] = key; } }
procedure insertsort; var i,j,key:integer; begin arr[0] := -maxint; for j := 2 to n do begin i := j - 1; key := arr[j]; while arr[i] > key do begin arr[i + 1] := arr[i]; i := i - 1; end; arr[i + 1] := key; end; end;