📚 排序算法概述
插入排序(Insertion Sort)
核心思想:将未排序的元素逐个插入到已排序部分的正确位置,就像打扑克牌时整理手牌一样。
桶排序(Bucket Sort)
核心思想:将数据分到有限数量的桶中,每个桶再分别排序(可以使用其他排序算法或递归使用桶排序),最后将各个桶中的数据合并。
💡 桶排序的关键:
• 适用于均匀分布的数据
• 桶的数量影响性能
• 通常用于浮点数排序
• 时间复杂度可达O(n)(理想情况)
⚙️ 算法实现
插入排序完整实现
#include <iostream>
using namespace std;
void insertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
void printArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
int arr[] = {12, 11, 13, 5, 6};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "排序前:";
printArray(arr, n);
insertionSort(arr, n);
cout << "排序后:";
printArray(arr, n);
return 0;
}
桶排序完整实现
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void bucketSort(float arr[], int n) {
vector<vector<float>> buckets(n);
for (int i = 0; i < n; i++) {
int bucketIndex = n * arr[i];
buckets[bucketIndex].push_back(arr[i]);
}
for (int i = 0; i < n; i++) {
sort(buckets[i].begin(), buckets[i].end());
}
int index = 0;
for (int i = 0; i < n; i++) {
for (size_t j = 0; j < buckets[i].size(); j++) {
arr[index++] = buckets[i][j];
}
}
}
void printArray(float arr[], int n) {
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
int main() {
float arr[] = {0.78, 0.17, 0.39, 0.26, 0.72,
0.94, 0.21, 0.12, 0.23, 0.68};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "排序前:";
printArray(arr, n);
bucketSort(arr, n);
cout << "排序后:";
printArray(arr, n);
return 0;
}
🎮 互动实验:排序演示
输入数组元素,查看两种排序的过程
输入数组后点击按钮...
🛠️ 算法比较
两种排序的对比
| 特性 |
插入排序 |
桶排序 |
| 最好时间复杂度 |
O(n)(已有序) |
O(n+k) |
| 平均时间复杂度 |
O(n²) |
O(n+k) |
| 最坏时间复杂度 |
O(n²) |
O(n²) |
| 空间复杂度 |
O(1) |
O(n+k) |
| 稳定性 |
稳定 |
稳定 |
| 数据类型 |
整数、浮点数 |
主要用于浮点数 |
| 适用场景 |
小数据、近乎有序 |
均匀分布的数据 |
💡 关键区别:
• 插入排序:原地排序,适合小规模数据,几乎有序时效率极高
• 桶排序:需要额外空间,适合均匀分布的浮点数,理想情况下O(n)
• k表示桶的数量,通常k≈n时性能最佳
插入排序的优势场景
int arr1[] = {1, 2, 3, 5, 4};
int arr2[] = {5, 3, 8, 1};
桶排序的优势场景
float arr[] = {0.12, 0.34, 0.56, 0.78, 0.91};
实际应用:考试成绩排序
#include <iostream>
#include <vector>
using namespace std;
void sortScores(double scores[], int n) {
for (int i = 1; i < n; i++) {
double key = scores[i];
int j = i - 1;
while (j >= 0 && scores[j] < key) {
scores[j + 1] = scores[j];
j--;
}
scores[j + 1] = key;
}
}
int main() {
double scores[] = {85.5, 92.0, 78.5, 95.0, 88.0};
int n = 5;
cout << "=== 成绩排名(从高到低)===" << endl;
sortScores(scores, n);
for (int i = 0; i < n; i++) {
cout << (i+1) << ". " << scores[i] << "分" << endl;
}
return 0;
}
🚀 性能分析与优化
插入排序的时间复杂度分析
| 情况 |
比较次数 |
移动次数 |
时间复杂度 |
| 最好(已有序) |
n-1 |
0 |
O(n) |
| 最坏(逆序) |
n(n-1)/2 |
n(n-1)/2 |
O(n²) |
| 平均(随机) |
n²/4 |
n²/4 |
O(n²) |
桶排序的时间复杂度分析
💡 桶排序性能关键:
• 桶的数量k应该接近n
• 数据应该均匀分布
• 桶内排序算法的选择影响性能
• 理想情况下可以达到O(n)
插入排序的优化:二分插入
#include <iostream>
using namespace std;
int binarySearch(int arr[], int left, int right, int key) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == key) {
return mid + 1;
} else if (arr[mid] < key) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
}
void binaryInsertionSort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int pos = binarySearch(arr, 0, i - 1, key);
for (int j = i - 1; j >= pos; j--) {
arr[j + 1] = arr[j];
}
arr[pos] = key;
}
}
📝 实战练习
📝 理解测试
对于近乎有序的数组 [1, 2, 3, 5, 4],哪种排序算法最快?
选择答案查看解析...
💻 综合挑战
题目:实现一个完整的排序比较程序:
1. 生成随机数组
2. 分别用插入排序和桶排序进行排序
3. 统计两种排序的执行时间
4. 验证排序结果是否正确
5. 分析两种算法的性能差异
点击"生成代码框架"查看提示...