直接插入排序的一种实现:
public IList<int> InsertionSort(int[] ary) { var len = ary.Length; for (int i = 1; i < len; i++) { var key = ary[i]; for (int j = 0; j < i; j++)//从前向后找 { if (key < ary[j]) { for (int k = i; k > j; k--)//从后向前逐个移动 { ary[k] = ary[k - 1]; } ary[j] = key; break;//每次插入一个值后,完成此次遍历 } } } return ary.ToList(); }
这种方法,是从小到大(从左到右)的顺序来寻找插入的位置,每次循环,在已排好的列表中,找到“第一个”,比当前要插入的值大的数,然后从最后一个位置开始,从右向左逐个后移,空出这个比当前值大的数的位置后,将当前值插入进去。然后结束本次的循环。看代码可发现,这种方式写起来略微复杂。
另一种实现方法,是从大到小(从右到左)的顺序来找插入的位置,代码如下:
public IList<int> InsertionSort(int[] ary) { var len = ary.Length; for (int i = 1; i < len; i++) { var key = ary[i]; int j = i - 1; while (j >= 0 && key < ary[j])//从后往前,一边找一边移动 { ary[j + 1] = ary[j]; j--; } ary[j + 1] = key; } return ary.ToList(); }
外部循环一样,内部循环,每次从最后一个已排好序的元素开始,使用while一边比较一边移动。如果已排序的值小于当前要插入的值,则结束循环。这时要插入的位置也已经疼出来了,只需将当前值插入即可。这里因为每次做了j--,因此在插入的时候,需要先进行加1。
直接插入排序的特点是使用“常数个”额外的内存空间,即空间复杂度为O(1)。而时间复杂度是O(n*n)。