数据结构:常见的排序算法(三):二分插入排序(C++实现)

数据结构:常见的排序算法(三):二分插入排序

插入排序:

1.思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置,直到全部插入排序完为止。
2.关键问题:在前面已经排好序的序列中找到合适的插入位置。
方法: 分为 直接插入排序二分插入排序希尔排序

二分插入排序

1.基本思想:

基本思想:二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。

二分法插入排序,简称二分排序,是在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left<right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。

根据二分查找的思想,将待查入记录分为有序表和无序表,每次取无序表的第一个关键字与有序表中间位置的记录与作比较。如果小于该记录,则将元素插入后面的子表中,反之,如果大于该记录,则将元素插入前面的子表中。反复迭代,直至所有记录全部插入表中。

2.示例

将数组a[6]={5,36,24,10,6,12}通过二分插入排序进行排序

img

图片来源:https://www.cnblogs.com/zwtgyh/p/10631760.html

代码实现

#include<iostream>
using namespace std;
/*二分查找函数,返回插入下标*/
template <typename T>
int BinarySearch(T array[], int start, int end, T k)
{
	while (start <= end)
	{
		int middle = (start + end) / 2;
		int middleData = array[middle];
		if (middleData > k)
		{
			end = middle - 1;
		}
		else
			start = middle + 1;
	}
	return start;
}
//二叉查找插入排序
template <typename T>
void InsertSort(T array[], int length)
{
	if (array == nullptr || length < 0)
		return;
	int i, j;
	for (i = 1; i < length; i++)
	{
		if (array[i]<array[i - 1])
		{
			int temp = array[i];
			int insertIndex = BinarySearch(array, 0, i, array[i]);//使用二分查找在有序序列中进行查找,获取插入下标
			for (j = i - 1; j >= insertIndex; j--) //移动元素
			{
				array[j + 1] = array[j];
			}
			array[insertIndex] = temp;    //插入元素
		}
	}
}
//主函数
int main() {
	//int *a = Random();
	int a[6] = { 5, 36, 24, 10, 6, 12 };
	InsertSort(a, 6);
	for (int i = 0; i < 6; i++)
	{cout << a[i] << " ";}	
	cout << endl;
	return 0;
}

3.总结:

1、总结:最坏情况:每次都在有序序列的起始位置插入,则整个有序序列的元素需要后移,时间复杂度为O(n2)

2、最好情况:待排序数组本身就是正序的,每个元素所在位置即为它的插入位置,此时时间复杂度仅为比较时的3、时间复杂度,为O(log2n)

4、平均情况:O(n2)

空间复杂度上,二分插入也是就地排序,空间复杂度为(O(1))。

猜你喜欢

转载自blog.csdn.net/qq_43801020/article/details/108108187