插入排序: 插入排序,每一步将一个新的元素插入到前面已经排好序的一组元素的合适位置上去,直到全部元素插入为止。
插入排序比较适合的场景是元素已经接近有序,这样的场景下插入排序的效率较高。
最优情况下:时间复杂度可达到O(N)。
最差情况下:时间复杂度会达到O(N^2)。
空间复杂度:O(1),并且这是一种稳定的算法。
稳定:如果a,b两个元素的值相等,排序之前a在前,b在后,而排序之后,a仍然在前,b仍然在后,那么我们就称这种排序算法稳定。
来看看插入排序的代码:
void InsertSort(int arr[], int size)
{
int i = 1;
//如果只有一个元素,我们认为它有序
for (; 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;
}
}
优化:我们可以看到在插入排序的时候,前面的序列已经有序,那么我们可以使用二分查找对其进行优化,在新元素到来的时候,使用二分查找对其定位,然后直接进行插入。
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;
}
}