排序算法——折半插入排序

263 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

折半插入排序:

折半插入排序(Binary Insertion Sort)是对插入排序算法的一种改进。所谓插入排序,就是不断的依次将元素插入前面已排好序的序列中。
折半插入排序也是插入排序的一种。

思路分析:

折半插入排序与直接插入排序相类似,都是取数字、找位置、移动、插入这四步。它们之间的差别在于找位置的方法不同,折半插入排序的思想与折半查找思路相同(用low指针和high指针不断地更新指针来找位置)

算法核心:

void BInsertSort(int a[], int n) {
	int low = 0, high = 0, temp = 0, j = 0;
	for (int i = 1; i < n; i++) {
		temp = a[i];
		low = 0;
		high = i - 1;
		//找位置
		while (low <= high) {
			int mid = (low + high) / 2;
			if (temp < a[mid])
				high = mid - 1;
			else
				low = mid + 1;
		}
		//移动
		for (j = i - 1; j >= high + 1; j--)
			a[j + 1] = a[j];
		a[j + 1] = temp;
	}
}

算法思路:

1.从数组的第二个数据开始,进行第一层循环
2.low指针指向位置0
3.high指针指向位置i-1
4.利用折半查找的思想找到要插入的位置
5.查找结束后,利用high指针的位置来进行第二层循环来移动
6.移动完成后,就是插入——a[j+1]=temp

代码如下:

//关键点
// 1.将要插入的值取出来(temp)
// 2.利用折半查找的思想找到high的值
// 3.不断地移动
// 4.插入
#include<iostream>
using namespace std;
void BInsertSort(int a[], int n) {
	int low = 0, high = 0, temp = 0, j = 0;
	for (int i = 1; i < n; i++) {
		temp = a[i];
		low = 0;
		high = i - 1;
		//找位置
		while (low <= high) {
			int mid = (low + high) / 2;
			if (temp < a[mid])
				high = mid - 1;
			else
				low = mid + 1;
		}
		//移动
		for (j = i - 1; j >= high + 1; j--)
			a[j + 1] = a[j];
		a[j + 1] = temp;
	}
}
int main()
{
	int n;
	cin >> n;
	int* a = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	BInsertSort(a, n);
	for (int i = 0; i < n; i++) {
		cout << a[i] << "  ";
	}
}

复杂度分析:

时间复杂度:

最好: O(nlog2n)
最坏: O(n²)
平均: O(n²)

空间复杂度:

用了一个temp中间变量,O(1)

特点:

1.稳定排序
2.适用于数组(顺序存储结构),不适用于链式存储结构 PS: 对于这种比较简单的排序方式,时间复杂度都会比较高,当n比较大时,不适用!