时间复杂度为 O(N*logN)
heapinsert用于创建大堆时的向上调整,heapify用于对该节点向下调整大堆
class Solution {
public:
//建一个大堆
//在i的位置向上调整
void heapinsert(vector<int>& nums,int i)
{
while (nums[i]>nums[(i-1)/2])
{
swap(nums[i], nums[(i - 1) / 2]);
i = (i - 1) / 2;
}
}
//向下调整,设当前heap的大小为size,i为当前调整的位置
void heapify(vector<int>&nums,int i,int size)
{
int l = 2 * i + 1;
while (l<size)
{
//先找到两个儿子里的最大值
int best = l + 1 < size && nums[l + 1] > nums[l] ? l + 1 : l;
if (nums[i]<nums[best])
{
swap(nums[i], nums[best]);
i = best;
l = 2 * i + 1;
}
else
{
break;
}
}
}
void heapsort(vector<int>&nums)
{
//正常建一个大堆,时间复杂度O(N*logN)
for (int i=0;i<nums.size();i++)
{
heapinsert(nums,i);
}
//堆排序:每次把堆顶的数和数组的最后交换,因为对顶可能是数组的最大值,然后在对堆0处向下调整
int size = nums.size();//设置堆的长度
while (size>1)
{
swap(nums[0],nums[--size]);
heapify(nums,0,size);
}
}
//两种排序的时间复杂度都是O(n*logn)
void heapsort2(vector<int>&nums)
{
//建大堆的另一种方式,就是从下往上建堆,因为越到后面,左右孩子就越多
//反而heapify遍历越快,约到上面越多,时间复杂度为O(N)
int size = 0;
for (int i=nums.size()-1;i>=0;i--)
{
heapify(nums,i,++size);
}
//根据堆的特性进行排序
while (size > 1)
{
swap(nums[0], nums[--size]);
heapify(nums, 0, size);
}
}
};