前言
在众多排序算法中,插入排序(Insertion Sort)以其简单直观、实现容易的特点,常作为新手学习排序算法的入门案例。
一、插入排序是什么?
插入排序是一种简单直观的排序算法,其基本思想是:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。它类似于一副扑克牌整理手牌的过程,左手依次抓取新牌,将其插入到右手已有的有序牌堆中。
-
时间复杂度
- 最好情况:O(n)(已基本有序)
- 最坏情况:O(n²)(逆序)
- 平均情况:O(n²)
-
空间复杂度:O(1)(原地排序)
-
稳定性:稳定排序
二、使用步骤
1. 引入头文件
#include <iostream>
#include <vector>
using namespace std;
2. 实现插入排序函数
插入排序的核心在于两层循环:外层遍历每个待插入元素,内层向前扫描并插入。
void insertionSort(vector<int>& arr) {
int n = arr.size();
for (int i = 1; i < n; ++i) {
int key = arr[i]; // 待插入的元素
int j = i - 1;
// 在已排序部分 arr[0..i-1] 中找到插入位置
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j]; // 元素后移
--j;
}
arr[j + 1] = key; // 插入
}
}
代码解析
- 外层循环
for (int i = 1; i < n; ++i)
:从第二个元素开始,将其视为“手中抓到的新牌”。 - 保存当前元素
key = arr[i]
:为了后移腾出位置。 - 内层循环
while (j >= 0 && arr[j] > key)
:比较并将大于key
的元素逐一后移。 - 插入
arr[j + 1] = key
:当找到合适位置时,将key
放入。
3. 测试排序结果
int main() {
vector<int> data = {5, 2, 9, 1, 5, 6};
cout << "排序前:";
for (int num : data) cout << num << " ";
cout << endl;
insertionSort(data);
cout << "排序后:";
for (int num : data) cout << num << " ";
cout << endl;
return 0;
}
运行结果:
排序前:5 2 9 1 5 6
排序后:1 2 5 5 6 9
三、学生成绩排序工具
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Student {
string name;
int score;
};
void insertionSort(vector<Student>& arr) {
int n = arr.size();
for (int i = 1; i < n; ++i) {
Student key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].score < key.score) { // 降序排序
arr[j + 1] = arr[j];
--j;
}
arr[j + 1] = key;
}
}
int main() {
vector<Student> students = {
{"Alice", 88}, {"Bob", 75}, {"Charlie", 93},
{"David", 85}, {"Eve", 90}
};
cout << "排序前:" << endl;
for (auto& s : students)
cout << s.name << ":" << s.score << endl;
insertionSort(students);
cout << "\n排序后(按成绩从高到低):" << endl;
int rank = 1;
for (auto& s : students)
cout << "第" << rank++ << "名 " << s.name << ":" << s.score << endl;
return 0;
}
项目说明:
- 定义
Student
结构体,包含name
和score
。 - 插入排序中比较条件由
arr[j].score > key.score
改为<
,实现降序。 - 输出学生排序前后的成绩及排名。
总结
插入排序作为基础排序算法,以其思路简单、实现便捷的特点,被广泛用于小规模数据的排序与部分有序数据的再次排序。虽然在大规模数据上效率有限,但其稳定性和原地排序的优势使其在某些场景下依然适用。