此为面经第十五谈!关注我,每日带你深入浅出一个新面经。
我们要了解面经要如何“说”!
很重要!很重要!很重要!
我们通常采取总-分-总方式来阐述!(有些知识点,你可以去了解,但是面经并不是需要全部了解的)
码农不易,各位学者学到东西请点赞支持支持!
排序算法部分可以记忆简单过程概述。
开始部分:
总:堆排序通过构建最大堆,然后逐步将堆顶元素与数组尾部元素交换并重新调整堆,直到完成排序。
分:
最好时间复杂度就是(n*k)
最差时间复杂度就是(n*k)
平均时间复杂度也是(n*k)
空间复杂度:n+k
稳定性:稳定。
#include <iostream>
#include <vector>
#include <algorithm> // 用于std::swap
using namespace std;
// 调整堆结构,确保堆的性质
void adjustHeap(vector<int>& arr, int i, int n) {
int temp = arr[i]; // 暂存当前节点值
for (int k = 2 * i + 1; k < n; k = k * 2 + 1) { // 从i节点的左子节点开始,也就是2i+1位置
if (k + 1 < n && arr[k] < arr[k + 1]) k++; // 如果有右子节点且右子节点值较大,则选择右子节点
if (arr[k] > temp) { // 如果子节点大于父节点
arr[i] = arr[k]; // 将较大的子节点值放到父节点上
i = k; // 继续向下调整
} else break; // 子节点小于父节点,调整结束
}
arr[i] = temp; // 将暂存的值放到最终位置
}
// 堆排序函数
void heapSort(vector<int>& arr) {
int n = arr.size(); // 获取数组长度
for (int i = n / 2 - 1; i >= 0; i--) { // 从最后一个非叶子节点开始调整为最大堆
adjustHeap(arr, i, n);
}
for (int j = n - 1; j > 0; j--) { // 交换堆顶元素与最后一个元素
swap(arr[0], arr[j]); // 交换操作
adjustHeap(arr, 0, j); // 重新调整堆
}
}
// 主函数,用于测试堆排序
int main() {
vector<int> arr = {3, 2, 5, 1, 7, 4, 6};
cout << "Original array: ";
for (int num : arr) cout << num << " ";
cout << endl;
heapSort(arr); // 调用堆排序函数
cout << "Sorted array: ";
for (int num : arr) cout << num << " ";
cout << endl;
return 0;
}
堆排序的步骤可以简化为以下几个关键点:
-
调整堆结构:
adjustHeap
函数用于将给定的数组元素调整为满足堆的性质,即父节点的值总是大于或等于其子节点的值(在最大堆中)。 -
构建最大堆:在
heapSort
函数中,从数组的最后一个非叶子节点开始,向下调用adjustHeap
函数,逐步调整整个数组为一个最大堆。 -
交换并重新调整:将堆顶元素(最大值)与数组的最后一个元素交换,然后减少堆的有效长度,并重新调整堆结构以保持最大堆的性质。
-
重复交换与调整:重复步骤 3,直到堆的大小减少到只剩下一个元素,此时整个数组就变成了有序的。
总:排序可视化网站(建议打开看着代码来了解)Heap Sort Visualization
看着排序过程来理解代码实现会更好。
学习链接:https://xxetb.xetslk.com/s/3Kif2D