折半插入排序


折半插入排序


一、基本概念
当直接插入排序进行到某一趟时,对于 r[i].key 来讲,前边 i-1 个记录已经按关键字有序。此时不用直接插入排序的方法,而改为折半查找,找出 r[i].key 应插的位置,然后插入。这种方法就是折半插入排序( Binary insertion sort )。


二、具体操作
在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],末元素设置为a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素大,则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]。


三、稳定性及复杂度
折半插入排序算法是一种稳定的排序算法,比直接插入算法明显减少了关键字之间比较的次数,因此速度比直接插入排序算法快,关键字的比较次数由于采用了折半查找而减少,数量级为O(nlog 2n) ,但记录移动的次数没有变,所以折半插入排序算法的时间复杂度仍然为O(n^2),与直接插入排序算法相同。附加空间O(1)。

四、示例代码:

public class ZhebanCharuPaixu {

	public static void main(String[] args) {
		// 待排序的数组
		int[] array = { 1, 0, 5, 3, 9, 10, 6, 7 };
		
		binaryInsertSort(array);
		
		// 显示排序后的结果
		System.out.print("排序后: ");
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + "->");
		}

	}

	private static void binaryInsertSort(int[] array) {
		if(array.length == 0){
			return;
		}
		
		for (int i = 1; i < array.length; i++) {
			int temp = array[i];
			int low = 0;
			int high = i - 1;
			
			while (low <= high) {
				// int mid = (high - low) / 2 + low; 
				// 下面这样可能会有整型溢出的问题
				int mid = (low + high) / 2;  
				
				if (temp < array[mid]) {
					high = mid - 1;
				} else {
					low = mid + 1;
				}
			}
			
			// 下面的for循环中,有人用 j > mid; 还有人用 j >= high + 1,这个还需要再看看
			for (int j = i; j >= low + 1; j--) {
				array[j] = array[j - 1];
			}
			
			array[low] = temp;  // 此处用 array[high+1] = temp; 也可

		}
	}

}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值