堆排序
建堆
堆的操作有两种:上升和下沉。
上升是对一个已有的堆插入新元素时采取的操作。将新元素放在最后面,然后依次执行上升操作。
下沉是对一个不正确的堆进行的修正操作。
堆排
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Heap
{
public:
Heap(vector<int> num) :nums(num) {};
//下沉操作
void downAdjust(int k, int n)
{
int temp = nums[k];
for (int i = k * 2 + 1; i < n; i = i * 2 + 1)
{
if (i + 1 < n && nums[i + 1] > nums[i]) i = i + 1;
if (temp > nums[i]) break;
nums[k] = nums[i];
k = i;
}
nums[k] = temp;
}
void heapSort()
{
//依次对非叶子节点进行下沉操作
int len = nums.size();
for (int i = (len-2)/2; i >= 0; i--)
downAdjust(i, len);
for (int i = len-1; i >= 0; i--)
{
swap(nums[0], nums[i]);
downAdjust(0, i);
}
}
vector<int> nums;
};
int main()
{
vector<int> nums = {1,2,7,0,4,3,2,4,5};
Heap h(nums);
h.heapSort();
for (auto i : h.nums) cout << i << " ";
return 0;
}
下沉操作的时间复杂度是O(logn),整个建堆的时间复杂度是O(nlogn)
堆排的空间复杂度是O(1),时间复杂度是O(nlogn)