繼插入排序①,這裏說一下折半插入排序。
從前面的循環中可以看出直接插入排序是邊比較邊移動的。
這裏講的折半插入排序則是將比較和移動分開。(不斷的折半查找定位再一次性的移動元素,最終插入元素)
void InsertSort(int a[],int n)
{
int i,j,low,high,mid;//i用來遍歷序列,j用來移動元素
for(i=2;i<=n;i++)//默認第一個元素有序,用大循環處理所有元素
{
a[0]=a[i]; //用a[0]來當哨兵,即存儲要插入的值
low=1;//low,high用來定位
high=i-1;//要把第i個元素插到已經排好序的序列中
while(low<=high)//依次找,直到找到合適的位置
{
mid=(low+high)/2;
if(a[mid]>a[0])//中間元素大於要插入的元素,則在前半部分
{
high=mid-1;
}
else //中間元素小於要插入的元素,則在後半部分
{
low=mid+1;
}
}
for(j=i-1;j>=high+1;--j)//從後向前移動元素
{
a[j+1]=a[j];
}
a[high+1]=a[0];
//到此序列中一個元素處理結束
}
}
上述代碼註釋很詳細,就簡單的舉個例子吧,
比如序列:5,4
開始5在有序序列中,然後從第二個元素即4開始插入,low和high均指向了5,滿足while循環。此時high減一,不滿足循環,進入for循環,將5向後移,4插入即可。
時間複雜度:雖然查找位置優化了性能,但是移動原理和①相同,所以時間複雜度還是O(n*n)
穩定性:穩定