此为面经第十一谈!关注我,每日带你深入浅出一个新面经。
我们要了解面经要如何“说”!
很重要!很重要!很重要!
我们通常采取总-分-总方式来阐述!(有些知识点,你可以去了解,但是面经并不是需要全部了解的)
码农不易,各位学者学到东西请点赞支持支持!
排序算法部分可以记忆简单过程概述。
开始部分:
总:归并排序是用的是分治、递归思想。将数组分解至单一元素然后再组合成有序的数组。
分:
最好时间复杂度就是(nlogn)(只在外层循环遍历一次就排序完成)
最差时间复杂度就是(nlogn)
平均时间复杂度也是(nlogn)
空间复杂度:n
稳定性:稳定。
归并排序算法实现:
#include <iostream>
#include <vector>
// 合并两个有序数组的函数
void merge(std::vector<int>& arr, int left, int mid, int right) {
// 计算左子数组和右子数组的大小
int n1 = mid - left + 1; // 左子数组的大小
int n2 = right - mid; // 右子数组的大小
// 创建临时数组用于存储左子数组和右子数组
std::vector<int> L(n1); // 临时左子数组
std::vector<int> R(n2); // 临时右子数组
// 复制数据到临时左子数组 L
for (int i = 0; i < n1; i++)
L[i] = arr[left + i]; // 例如:L = [12, 11, 13],当 left = 0, mid = 2
// 复制数据到临时右子数组 R
for (int j = 0; j < n2; j++)
R[j] = arr[mid + 1 + j]; // 例如:R = [5, 6, 7],当 mid = 2, right = 5
// 合并临时数组 L 和 R 到原数组 arr
int i = 0; // 左子数组的初始索引
int j = 0; // 右子数组的初始索引
int k = left; // 合并部分的初始索引
// 合并过程
while (i < n1 && j < n2) { // 当左子数组和右子数组都有剩余元素时
if (L[i] <= R[j]) { // 如果左子数组的当前元素小于等于右子数组的当前元素
arr[k] = L[i]; // 将左子数组的当前元素放入原数组中
i++; // 移动左子数组的索引
} else {
arr[k] = R[j]; // 将右子数组的当前元素放入原数组中
j++; // 移动右子数组的索引
}
k++; // 移动原数组的索引
}
// 复制左子数组中剩余的元素(如果有的话)
while (i < n1) { // 如果左子数组还有剩余元素
arr[k] = L[i]; // 将剩余的左子数组元素放入原数组中
i++; // 移动左子数组的索引
k++; // 移动原数组的索引
}
// 复制右子数组中剩余的元素(如果有的话)
while (j < n2) { // 如果右子数组还有剩余元素
arr[k] = R[j]; // 将剩余的右子数组元素放入原数组中
j++; // 移动右子数组的索引
k++; // 移动原数组的索引
}
}
// 递归地分割和排序数组的函数
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) { // 当左边界小于右边界时
// 计算中间点
int mid = left + (right - left) / 2;
// 递归地排序左半部分
mergeSort(arr, left, mid);
// 递归地排序右半部分
mergeSort(arr, mid + 1, right);
// 合并已排序的子数组
merge(arr, left, mid, right);
}
}
// 打印数组的函数
void printArray(const std::vector<int>& arr) {
for (int num : arr) // 遍历数组中的每个元素
std::cout << num << " "; // 打印元素
std::cout << std::endl; // 打印换行符
}
// 主函数
int main() {
// 初始化数组
std::vector<int> arr = {12, 11, 13, 5, 6, 7};
std::cout << "Given array is \n";
printArray(arr); // 打印排序前的数组
// 调用 mergeSort 函数对数组进行排序
mergeSort(arr, 0, arr.size() - 1);
std::cout << "\nSorted array is \n";
printArray(arr); // 打印排序后的数组
return 0; // 程序结束
}
归并排序的简单概述过程:
- 分解:将数组递归地分成两半,直到每半包含一个元素。
- 合并:将两个有序的单元素数组合并成有序的双元素数组。
- 递归合并:重复合并过程,逐步合并成更大的有序数组。
总: 排序可视化网站(建议打开看着代码来了解)Comparison Sorting Visualization (usfca.edu)
看着排序过程来理解代码实现会更好。
归并排序的关键在于合并步骤,这一步骤需要仔细地将两个有序子数组合并成一个更大的有序数组。这个过程是递归地进行,直到最终整个数组变得有序。