目录
4.1 排序算法
4.1.1 各种排序算法的时间空间复杂度、稳定性 ⭐⭐⭐⭐⭐
排序算法 | 平均时间复杂度 | 最好情况时间复杂度 | 最坏情况时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n^2) | O(n) | O(n^2) | O(1) | 稳定 |
选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 不稳定 |
插入排序 | O(n^2) | O(n) | O(n^2) | O(1) | 稳定 |
希尔排序 | O(n log n) | O(n log^2 n) | O(n^2) | O(1) | 不稳定 |
归并排序 | O(n log n) | O(n log n) | O(n log n) | O(n) | 稳定 |
快速排序 | O(n log n) | O(n log n) | O(n^2) | O(log n) | 不稳定 |
- 稳定性:指的是如果两个元素相等,它们在排序前后的相对位置是否保持不变。
- 时间复杂度:算法执行所需的时间,通常表示为最坏、平均和最好情况。
- 空间复杂度:算法执行时所需的额外存储空间。
4.1.2 各种排序算法什么时候有最好情况、最坏情况(尤其是快排) ⭐⭐⭐⭐
-
冒泡排序:
- 最好情况:数组已经有序,时间复杂度为 O(n)。
- 最坏情况:数组逆序,时间复杂度为 O(n^2)。
-
选择排序:
- 无论数组是否有序,最好和最坏情况的时间复杂度都是 O(n^2)。
-
插入排序:
- 最好情况:数组已经有序,时间复杂度为 O(n)。
- 最坏情况:数组逆序,时间复杂度为 O(n^2)。
-
希尔排序:
- 最好情况:数组基本有序,时间复杂度接近 O(n log n)。
- 最坏情况:数组完全无序,时间复杂度为 O(n^2)。
-
归并排序:
- 最好和最坏情况的时间复杂度都是 O(n log n),因为归并排序是分治算法,分割和合并的过程都不会依赖于数据的顺序。
-
快速排序:
- 最好情况:每次分割点恰好是数组的中位数,时间复杂度为 O(n log n)。
- 最坏情况:每次分割点总是选择最大或最小值,时间复杂度为 O(n^2)(通常在数组几乎有序或完全无序时发生)。改进方式是使用随机化或三数取中。
4.1.3 冒泡排序 ⭐⭐⭐⭐
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
bool swapped = false;
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
std::swap(arr[j], arr[j + 1]);
swapped = true;
}
}
if (!swapped)
break;
}
}
4.1.4 选择排序 ⭐⭐⭐⭐
void selectionSort