插入排序
- 直接插入排序
- 希尔排序
基本思想:每一步将一个待排序的元素,按照其排序码的大小,插入到前面已经排好序的一组元素的合适位置上去,直到元素全部插完为止。
直接插入排序
代码实现:
void InsertSort(int arr[], int size)
{
for (int i = 1; i < size; i++)
{
int key = arr[i];
int end = i - 1;
while (end >= 0 && key < arr[end])
{
arr[end + 1] = arr[end];
end--;
}
arr[end + 1] = key;
}
}
元素集合越接近有序,直接插入排序算法的时间效率就越高。
所以考虑到这点可以使用折半查找算法对其进行优化,该优化只减少了在有序区域比较的次数,并没有减少元素移动数。
时间复杂度:最优情况,待排序序列接近有序,要移动的关键字只有常数此,它的时间复杂度O(n),最坏情况,待排序序列基本无序,时间复杂度为O(N*N)。
空间复杂度:只开辟了一个空间所以为O(1)。
void InsertSort(int arr[], int size)
{
for (int i = 1; i < size; ++i)
{
int key = arr[i];
int end = i - 1;
int left = 0;
//二分查找先找到位置
int right = i - 1;
while (left <= right)
{
int mid = left + ((right - left)>>1);
if (arr[mid]>key)
right = mid - 1;
else
left = mid + 1;
}
while (end >=left)
{
arr[end + 1] = arr[end];
end--;
}
arr[end + 1] = key;
}
}
希尔排序
又称缩小增量排序,也是对直接插入排序的优化
代码实现:
void ShellSort(int arr[], int size)
{
int gap = size;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = gap; i < size; i += gap)
{
int key = arr[i];
int end = i - gap;
while (end >= 0 && arr[end]>key)
{
arr[end + gap] = arr[end];
end -= gap;
}
arr[end + gap] = key;
}
}
}```
希尔排序使较大的数据往后移动,接近有序,所以效率比直接插入排序要搞,但是数据的位置改变,所以**不稳定**,平均时间复杂度为n*log(n)