堆结构和堆排序

时间复杂度为 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);
        }
    }
};
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值