此为面经第十二谈!关注我,每日带你深入浅出一个新面经。
我们要了解面经要如何“说”!
很重要!很重要!很重要!
我们通常采取总-分-总方式来阐述!(有些知识点,你可以去了解,但是面经并不是需要全部了解的)
码农不易,各位学者学到东西请点赞支持支持!
排序算法部分可以记忆简单过程概述。
开始部分:
总:计数排序是一种基于三个数组(原始数组、计数数组、输出数组)的排序算法。
分:
最好时间复杂度就是(n+k)
最差时间复杂度就是(n+k)
平均时间复杂度也是(n+k)
空间复杂度:n+k
稳定性:稳定。
计数排序算法的实现:
#include <iostream>
#include <vector>
// 计数排序函数
void countingSort(std::vector<int>& arr) {
if (arr.empty()) return; // 如果数组为空,直接返回
// 找到数组中的最大值和最小值
int max_val = *max_element(arr.begin(), arr.end()); // 最大值
int min_val = *min_element(arr.begin(), arr.end()); // 最小值
// 创建计数数组
int range = max_val - min_val + 1; // 数值范围的大小
std::vector<int> count(range, 0); // 初始化计数数组,大小为 range
// 统计每个元素的出现次数
for (int num : arr) {
count[num - min_val]++; // 通过调整索引位置来统计出现次数
}
// 将计数数组中的元素转换为累积计数,用作偏移量,因为一个数可能会有几个以上
for (int i = 1; i < range; ++i) {
count[i] += count[i - 1]; // 累积计数
}
// 创建输出数组
std::vector<int> output(arr.size()); // 用于存储排序后的数组
// 将元素放到输出数组中
for (int i = arr.size() - 1; i >= 0; --i) {
output[count[arr[i] - min_val] - 1] = arr[i]; // 根据计数结果放置元素
count[arr[i] - min_val]--; // 更新计数
}
// 将排序后的数组复制回原数组
for (int i = 0; i < arr.size(); ++i) {
arr[i] = output[i]; // 复制排序后的结果
}
}
// 打印数组的函数
void printArray(const std::vector<int>& arr) {
for (int num : arr) // 遍历数组中的每个元素
std::cout << num << " "; // 打印元素
std::cout << std::endl; // 打印换行符
}
// 主函数
int main() {
// 初始化数组
std::vector<int> arr = {4, 2, 2, 8, 3, 3, 1};
std::cout << "Given array is \n";
printArray(arr); // 打印排序前的数组
// 调用 countingSort 函数对数组进行排序
countingSort(arr);
std::cout << "\nSorted array is \n";
printArray(arr); // 打印排序后的数组
return 0; // 程序结束
}
计数排序的简单概述过程:
-
找到最大和最小元素:确定数组中的最大值和最小值,以确定计数数组的范围。
-
创建计数数组:初始化一个计数数组,其大小为最大值与最小值之差加1,所有元素初始值为0。
-
统计频率:遍历原数组,根据元素值在计数数组中相应位置加1。
-
计算累积计数:将计数数组中的每个元素加上前一个元素的值,得到累积计数。便于输出数组的正确偏移量位置。
-
创建输出数组:初始化一个输出数组,用于存放排序后的结果。
-
放置元素:根据累积计数和原数组的元素值,将元素放置到输出数组的正确位置。
-
复制回原数组:将输出数组中的排序结果复制回原数组。
总: 排序可视化网站(建议打开看着代码来了解)Counting Sort Visualization (usfca.edu)
看着排序过程来理解代码实现会更好。
简单来说,计数排序通过统计每个元素的出现次数,然后使用累积计数来确定每个元素在最终排序数组中的位置。