【算法】折半插入排序

先查找中间元素再插入排序

活动地址:CSDN21天学习挑战赛

目录

1.折半插入排序

1.1 定义

1.2 说明

1.3 代码示例

1.4 复杂度

1.5 优缺点

2. 搜索插入位置

扫描二维码关注公众号,回复: 14485003 查看本文章

2.1 说明

2.2 解法

2.3 代码示例

2.4 复杂度


1.折半插入排序

1.1 定义

折半插入排序与直接插入排序算法原理相同。只是,在向已排序的数据中插入数据时,采用来折半查找(二分查找)。先取已经排序的序列的中间元素,与待插入的数据进行比较,如果中间元素的值大于待插入的数据,那么待插入的数据属于数组的前半部分,否则属于后半部分。依次类推,不断缩小范围,确定要插入的位置。

1.2 说明

待排序数据:3,2,5,7,4

取第一个元素作为有序表,剩余的元素作为无序表

   其中有序表:3;无序表:2,5,7,4

第一次比较,从无序表中取出第一个数 2,与中间值3比较,2<3,2插到3的前面,得到

   有序表:2,3;无序表:5,7,4

第二次比较,从无序表中取出第一个数 6,与中间值1比较,6>1,要放在1的后面,再与后半区(有序表:3)的中间值3比较,5>3,5插入到3的后面,得到

   有序表:2,3,5;无序表:7,4

第三次比较,从无序表中取出第一个数 7,与中间值2比较,7>2,7放在2后面,再与后半区(有序表:5)的中间值5比较,7>5,7放在5后面,得到

   有序表:2,3,5,7;无序表:4

第四次比较,从无序表中取出第一个数 4,与中间值3比较,4>3,4放在3后面,再与后半区(有序表:5,7)的中间值5比较,4<5,4放在5前面,最终得到:

   2,3,4,5,7

1.3 代码示例

public void sortNums(int[] array) {
	
	for (int i = 1; i < array.length; i++) {
		int left = 0;
		int right = i-1;
		int temp = array[i];

		while(left <= right) {
			int mid = (left + right) / 2;
			if (array[mid] > temp) {
				right = mid - 1;
			} else {
				left = mid + 1;
			}
		}
		for (int j = i -1; j > right; j--) {
			array[j+1] = array[j];
		}
		array[right+1] = temp;
	}
}

1.4 复杂度

时间复杂度:O(n^2)

空间复杂度: 0(1)

1.5 优缺点

优点:折半插入排序相对稳定,相对于直接插入排序,减少了比较次数;但是相对直接插入排序,移动次数不变。

缺点:进行n次的二分查找

2. 搜索插入位置

2.1 说明

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

2.2 解法

使用二分查找

2.3 代码示例

 public int searchInsert(int[] nums, int target) {
 	int left = 0;
 	int right = nums.length - 1;
 	while(left <= right) {
 		int mid = left + (right-left) /2;
 		if (nums[mid] == target) {
 			return mid;
 		} else if(nums[mid] > target){
 			right = mid -1;
 		} else {
 			left = mid + 1;
 		}
 	}
 	return left;
 }

2.4 复杂度

时间复杂度:O(log n),其中 n 为数组的长度。二分查找所需的时间复杂度为 O(logn)。

空间复杂度:O(1)。我们只需要常数空间存放若干变量。

猜你喜欢

转载自blog.csdn.net/m0_60494863/article/details/126293731