先查找中间元素再插入排序
活动地址:CSDN21天学习挑战赛
目录
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)。我们只需要常数空间存放若干变量。