排序算法——直接插入排序

1,713 阅读2分钟

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

直接插入排序:

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。

算法过程思路:

c335cd1c29185cbc0d15360f1ae72ff.jpg (图片来源:《数据结构(C语言版)》严蔚敏著)

算法核心:

void InsertSort(int a[], int n) {
	int temp = 0, j = 0;
	for (int i = 1; i < n; i++) {
		if (a[i] < a[i - 1]) {
			temp = a[i];
			for (j = i - 1; j >= 0 && temp < a[j]; j--)
				a[j + 1] = a[j];//后移
			a[j + 1] = temp;
		}
	}
}

算法思路分析:

1.从第二个位置开始,将会进行n-1次操作
2.若第当前位置比前一个位置的值小的话,设置一个中间变量来记录当前位置的值,进入下一层循环
3.第二层循环的目的是比较和移动
4.对于升序数组来说,第二层循环从数组的最后一位开始,不断地比较a[j],若temp的值比a[j]小的话,后移,直到找到一个a[j]比它大,这时第一层循环结束
5.在第一层循环的末尾,使a[j+1]=temp,一次循环结束。
6.下一次循环从i+1开始,而数组下标为0~i已经排好序了

代码如下(不带哨兵):

//关键点
// 1.如果需要插入,就把插入的值取出来
// 2.比数值大的数不断地后移,直到一个数小于或等于它
// 3.由于移动,使a[j+1]=temp值
#include<iostream>
using namespace std;
void InsertSort(int a[], int n) {
	int temp = 0, j = 0;
	for (int i = 1; i < n; i++) {
		if (a[i] < a[i - 1]) {
			temp = a[i];
			for (j = i - 1; j >= 0 && temp < a[j]; 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];
	}
	InsertSort(a, n);
	for (int i = 0; i < n; i++) {
		cout << a[i] << "  ";
	}
}

代码如下(带哨兵)

#include<iostream>
using namespace std;

void InsertSort(int a[], int n) {
	for (int i = 2; i <= n; i++) {
		if (a[i] < a[i - 1]) {
			a[0] = a[i];//a[0]是中间变量
			int j;
			//从i的前一个开始移动
			for (j = i - 1; a[0] < a[j]; j--) {
				a[j + 1] = a[j];//移动
			}
			a[j + 1] = a[0];
		}
	}
}

int main()
{
	int n;
	cin >> n;
	int* a = new int[n + 1];
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	InsertSort(a, n);
	for (int i = 1; i <= n; i++)
		cout << a[i] << " ";
}

复杂度分析:

时间复杂度:

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

空间复杂度:

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

特点:

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