从顺序查找到直接插入排序
无论从抽象过程还是具体实现代码来看,顺序查找是直接插入查找的基本组成元素。为什么这么说:
- 排序要遍历所有元素
- 从“未排序“数列中取出一个元素,插入到“已排序“数列中。需要在“已排序“数列中遍历到一个i,使得arr[i-1]<arr[i]<arr[i+1]。
需要两个基本的遍历过程。下面讨论算法的流程
直接插入排序的流程
首先脑海中要有一个基本模型:
【 {有序子序列} {当前待排序元素} {剩余待排序元素} 】
排序过程:
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序
注意:
有序子序列插入时,遍历不是从下标0开始,而是待排序元素的左边元素。

直接插入排序的性能
- Space Complexity: S(n)=O(1)
- Time Complexity: T(n)=O(\({n^2}\))
- 一种稳定排序方法
设对象个数为n,则执行n-1趟最坏情况下:第 i 趟比较i次,移动i次
最大比较次数:\(\frac{n(n-1)}{2}\)
最大移动次数:\(\frac{n(n-1)}{2}\)
最好情况下:每趟只需比较 1 次,不移动 总比较次数为 n-1次。
code
code 1(C++ Iterative)
void insertionSort(int arr[], int n)
{
int i, key, j;
for (i = 1; i < n; i++) //从下标为1的位置开始遍历
{
key = arr[i]; //保存待排序元素的值
j = i - 1; //从待排序元素的前一个开始
//找寻插入位置
while (j >= 0 && arr[j] > key) //循环条件1.不越界2.比key大
{
arr[j + 1] = arr[j];
--j;
}
arr[j + 1] = key; //移动key到待插入位置
}
}
code 2(C++ Recursive)
如果熟悉了直接插入排序,与递归技巧,不难发现如下关系:
\1. Base Case: If array size is 1 or smaller, return.
\2. Recursively sort first n-1 elements.
\3. Insert last element at its correct position in sorted array.
void insertionSortRecursive(int arr[], int n)
{
// Base case
if (n <= 1)
return;
// Sort first n-1 elements
insertionSortRecursive( arr, n-1 );
// Insert last element at its correct position
// in sorted array.
int last = arr[n-1];
int j = n-2;
/* Move elements of arr[0..i-1], that are
greater than key, to one position ahead
of their current position */
while (j >= 0 && arr[j] > last)
{
arr[j+1] = arr[j];
j--;
}
arr[j+1] = last;
}