直接插入排序(新手笔记)

前言:

本文章为新手书写,主要针对在编程题目中的一些基本算法题,也为自己写写笔记,如有瑕疵漏洞,欢迎各位在评论区给出见解。

注释:

直接插入排序是排序算法的冰山一角,还有很多高效率的排序算法。

一、直接插入排序思想讲解

直接插入排序可将乱序数组有序化,首先它从左至右(顺序可变)对数组进行有序化检查(数据从小到大),如果发现出错数据,即有大数据在小数据前面,则终止检查,将该小数据暂时保存,并从当前数据(比对数据)开始依次与暂存数据比对,如果发现比对数据大于暂存数据,则将比对数据向后移动一个位置,继续用它的前一个数据比对,当比对数据小于暂存数据时,就找到了正确插入地点,则可将暂存数据插入比对数据的后一个位置。循环该过程,直至最后一个数据插入完成。

二、直接插入排序代码展示

#include <iostream>
using namespace std;

int main()
{
	//输入数组元素个数
	int n;
	cin >> n;

	//创建数组,输入数据
	int* arr = new int[n];
	for (int i = 0; i < n; i++) {
		cin >> arr[i];
	}

	//直接插入排序思想代码
	for (int i = 2; i < n; i++) {

		//顺序检查
		if (arr[i - 1] > arr[i]) {
			int j;

			//暂存小数据
			int tmp = arr[i];

			//顺序比对
			for (j = i - 1; arr[j] > tmp && j >= 0; j--) {
				arr[j + 1] = arr[j];
			}

			//成功插入
			arr[j + 1] = tmp;
		}
	}

    //输出新数组
	for (int i = 0; i < n; i++) {
		cout << arr[i] << " ";
	}

	delete[] arr;
	return 0;
}

三、直接插入排序代码改进

在该程序代码中,有两处明显可以改进的地方(我已经在代码思想部分标红)。首先是 “ 暂时保存 ” 在代码中的体现是用一个tmp变量来存放,而使得在顺序比对时需要两个条件终止 “ arr[j] > tmp && j >= 0 ” ,我们可以用哨兵位置的思想改进,即先空出一个数组位置 arr[0] 来存放暂存数据,这样比对时就不用担心数组溢出了。其次是 “ 当前数据(比对数据)开始依次与暂存数据比对 这里由于顺序查找的特点,所以 for 语句中的 arr[j] > tmp 在第一次比较时会与 if 语句中的 arr[i - 1] > arr[i] 冲突,使效率变慢,我们可以跳过 for 语句中的第一次比较来改进代码。

#include <iostream>
using namespace std;

int main()
{
	//输入数组元素个数
	int n;
	cin >> n;

	//创建数组,输入数据
	int* arr = new int[n + 1];
	for (int i = 1; i < n + 1; i++) {
		cin >> arr[i];
	}

	//直接插入排序思想代码改进
	for (int i = 2; i <= n; i++) {

		//顺序检查
		if (arr[i - 1] > arr[i]) {
			int j;

			//设置哨兵位置
			arr[0] = arr[i];

			//首先交换
			arr[i] = arr[i - 1];
			
			//顺序比对
			for (j = i - 2; arr[j] > arr[0]; j--) {
				arr[j + 1] = arr[j];
			}

			//成功插入
			arr[j + 1] = arr[0];
		}
	}

	//输出新数组
	for (int i = 1; i < n + 1; i++) {
		cout << arr[i] << " ";
	}

	delete [] arr;
	return 0;
}

四、时间、空间复杂度

1、最好情况,即为顺序排列,如:1 2 3 4 5 6 7 8 9 10,时间复杂度为O(n)。

2、最坏情况,即为逆序排序,如:10 9 8 7 6 5 4 3 2 1,时间复杂度为O(n * n)。

3、平均情况为O(n * n)。

4、空间复杂度为O(1)。

结束语:

你们的点赞和关注是我创作的最大动力!此致!

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值