基本思想
每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的合适位置上去,直到元素全部插完为止。
直接插入排序
基本思想:当插入第i(i>=1)个元素时,前面的array[0],array[1],···,array[i - 1]已经排好序,此时用array[i]的排序码与array[i - 1],array[i - 2],···的排序码顺序进行比较,找到插入位置,原来的元素顺序后移。
程序代码:
void DirectInsertionSort(int* array, size_t n)//直接插入排序
{
for (size_t i = 1; i < n; i++)
{
int key = array[i];
int end = i - 1;
//1、已序序列中找待插入元素的位置并搬移
//大于key,搬移元素 比一次,搬一次
while (end >= 0 && key < array[end])
{
array[end + 1] = array[end];
end--;
}
//插入元素
array[end+1] = key;
}
}
时间复杂度:O(n)——O(n^2)
空间复杂度:O(1)
稳定性:稳定的
利用二分查找寻找要插入的位置
程序代码:
//利用二分查找去寻找插入位置
void DirectInsertionSort2(int* array, size_t n)
{
for (size_t i = 1; i < n; i++)
{
int key = array[i];
int left = 0;
int right = i - 1;
int mid = 0;
//1、已序序列中找待插入元素的位置
while (left <= right)
{
//二分查找
mid = left + ((right - left) >> 1);
if (key < array[mid])
right = mid - 1;
else
left = mid + 1;
}
//2、搬移元素(从后往前)
int end = i - 1;
while (end >= left)
{
array[end + 1] = array[end];
end--;
}
//3、插入元素
array[left] = key;
}
}
适用场景:
(1)数据量小
(2)接近有序
希尔排序
程序代码:
void ShellSort(int *array, size_t n)//希尔排序
{
int gap = n;
while (gap >= 1)
{
gap = gap / 3 + 1;
for (size_t i = gap; i < n; i++)
{
int key = array[i];
int end = i - gap;
while (end >= 0 && key < array[end])
{
array[end + gap] = array[end];
end -= gap;
}
array[end + gap] = key;
}
gap--;
}
}
时间复杂度:
空间复杂度:O(1)
稳定性:不稳定的
适用场景:数据量大