【排序】4.插入排序(含优化)
插入排序
1.步骤:
1.从第一个元素开始,该元素可以认为已经被排序
2.取下一个元素tem,从已排序的元素序列从后往前扫描
3.如果该元素大于tem,则将该元素移到下一位
4.重复步骤3,直到找到已排序元素中小于等于tem的元素
5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置
6.重复步骤2~5
2.动图演示
3.思路分析
思路:
在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个元素有序。按照此法对所有元素进行插入,直到整个序列有序。
但我们并不能确定待排元素中究竟哪一部分是有序的,所以我们一开始只能认为第一个元素是有序的,依次将其后面的元素插入到这个有序序列中来,直到整个序列有序为止。
4.代码实现
```java
void InsertSort(int* arr,int n)
{
for (int i = 0; i < n-1; i++)
{
//最后:end i-2 tem i-1
int end = i;
int tem = arr[end + 1]; //保存先,防止找不到
while (end >=0)
{
if (tem < arr[end]) //如果小于则交换到前面
{
arr[end + 1] = arr[end];
end--;
}
else
{
break;
}
//范围合适,放过来
//插入比它小的数后面
arr[end+1] = tem;
}
}
}
5.优化-折半插入
思路:用二分查找找到插入位置,再插入
//折半插入优化版本
void BinaryInsertSort(int* arr, int n)
{
for (int i = 1; i < n; i++)
{
int key = arr[i];
int left = 0;
int right = i - 1;
// 使用二分查找找到key应该插入的位置
while (left <= right)
{
int mid = left + (right - left) / 2;
if (key < arr[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
// 将key插入到正确的位置
// 从i开始,将所有元素向后移动,直到找到key应该插入的位置
for (int j = i; j > left; j--)
{
arr[j] = arr[j - 1];
}
arr[left] = key;
}
}