本系列文章旨在对排序算法做一个总结。
直接插入排序
概述
我们在待排序数组中实现插入排序,其中 insertSort 方法为排序的实现方法。
实现:将insertSort函数看为内外两个循环,外循环每次选一个新的待排序数,而内循环将此待排序数及其之前所有数变为有序的。每次执行一个外循环,有序数的个数加一,从而有序数越来越多,直至最终有序,排序结束。
初始时:外循环从待排序数组的第二位开始进行比较(与前一位进行比较),在内循环中选定该次循环待排序数的位置并放置(选定合适位置,便在该处该处插入元素,这就是为什么成为插入排序的原因)。
直接插入是稳定的排序方法。
直接插入排序算法的时间复杂度为o(n2),空间复杂度为1。
直接插入排序并不能保证每一次使得待排序数处于其最终位置(这是快排的特点),因为当前合适的插入位置并不代表最终的插入位置。
内循环的实现(找到当前的插入位置)是这个排序的重点。
代码实现(升序)
采用插入排序进行升序排列一个数组的算法如下(C/C++):
#include<iostream>
void insertSort(int* arr, int num);
int main() {
int a[10] = { 3, 2, 4, 6, 7, 5, 18, 9, 0, 1 };
for (int i = 0; i < 10; i++)
std::cout << a[i] << " ";
std::cout << '\n';
insertSort(a, 10);
for (int i = 0; i < 10; i++)
std::cout << a[i] << " ";
return 0;
}
void insertSort(int* arr, int num){
int temp, i, j;//temp保存每一次的新数,因为数组元素的移动会覆盖掉新数
for (i = 1; i < num; ++i){//所谓外循环,每次放一个新数进去参与排序
if (arr[i] < arr[i - 1]){//若下标i以前的数不是有序的,执行if语句内容
//此时的无序指的是下标0~i-1是有序的,需要将下标i中的数重新插入,使其变得有序
temp = arr[i];//保存每次的新数
for (j = i - 1; temp < arr[j] && j >= 0; --j)
arr[j + 1] = arr[j];
arr[j + 1] = temp;//在合适的位置上插入新数
}
}
}
降序算法如下
void insertSort(int* arr, int num){
int temp, i, j;
for (i = 1; i < num; ++i){
if (arr[i] > arr[i - 1]){
temp = arr[i];
for (j = i - 1; temp > arr[j] && j >= 0; --j)
arr[j + 1] = arr[j];
arr[j + 1] = temp;
}
}
}