排序(一)插入排序②

繼插入排序①,這裏說一下折半插入排序

從前面的循環中可以看出直接插入排序是邊比較邊移動的

這裏講的折半插入排序則是將比較和移動分開。(不斷的折半查找定位再一次性的移動元素,最終插入元素)

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)
穩定性:穩定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章