持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
直接插入排序:
直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。
算法过程思路:
(图片来源:《数据结构(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比较大时,不适用!