#include <iostream>
#include "iomanip"
using namespace std;
/*
直接插入排序
算法思想:1、默认第一个元素已经有序,接着把其后的元素都向前进行对比。
2、如果遇到比它还大的则将其前面的元素往后移。
算法实现分为两个部分:查找插入位置;移动元素;
*/
void insertSort(int a[] ,int n)//对数组下标1-n的元素进行排序
{
int i,j;
for(i = 2 ; i <= n ; i++)
{//从第二个元素开始往后进行排序
a[0] = a[i];//把a[0]当作哨兵
for(j = i-1 ; a[j]>a[0] ; j--)
{//从第i-1个元素向前找比i还要大的元素,把大的放后头。
a[j+1] = a[j];
}
a[j+1] = a[0];
}
}
/*
折半插入排序:
算法思想:缩短直接插入排序算法中查找每个元素插入位置的时间。
元素的插入仍然是要移动位于其之前的元素。
*/
void insertHalveSort(int a[] ,int n)
{
for(int i = 2 ; i <= n ; i++)
{
a[0] = a[i];//保存a[i]元素值
int low = 1, high = i-1;
//low变量代表着向后移动的元素下标
//折半查找元素插入的位置
while(low <= high)
{
int mid = (low+high)/2;
if(a[mid] > a[0]) high = mid-1;
else low = mid+1;
}
for(int j = i-1 ; j >= low ; j--) a[j+1] = a[j];
a[low] = a[0];
}
}
/*
关于i元素位置查找中插入位置的选择:
不管怎么样low最后都是比high大1,
造成low大于high时,mid元素与目标元素的大小关系有两种,
第一种是a[mid]大于T目标元素,则high左移构成low大于high,
而这代表low所指(即mid所指)元素的位置以后的元素要后移,
该low(mid)元素是i元素要放的位置。
第二种情况是a[mid]小于等于T目标元素,则left右移构成low大于high,
而这代表high所指(mid所指)元素是小于等于i元素,
因此low所指元素以后元素要后移,low所指元素是i元素要放的地方。
综上,都为low所指元素(包括low元素)以后都要向后移动。
*/
int main()
{
int a[10] = {1,9,2,0,12,4,5,3,7,10};
//BubbleSort(a ,10);
insertHalveSort(a , 9);
for(int i = 0 ; i < 10 ; i++)
printf("%d ",a[i]);
}