堆排序和N个数组的topK问题

本文详细介绍了堆排序的实现,包括heapify、heapInitial和heapSort三个核心函数,并探讨了堆排序的时间复杂度和应用场景,如解决大规模数据流的topK问题。此外,还提出了一种利用堆排序解决多个有序数组找TopK元素的方法,通过维护一个优先队列,依次处理每个数组的元素。
摘要由CSDN通过智能技术生成

堆排序

本文主要通过实现一个小根堆排序对堆排序进行一个说明。

堆排序具体分为以下几个函数进行实现:

  1. heapify(int[] nums, int n, int len)
  2. heapInitial(int[] nums, int n)
  3. heapSort(int[] nums)
heapify(int[] nums,int n, int len);

这个函数是堆排序的核心函数,其表示对n为下标的节点进行下筛操作。

  • 在n代表的节点、左孩子和右孩子三个节点中找到一个最小的节点
  • 将最小的节点交换到n的位置处(父节点处)
  • 如果n节点本身就是三个节点中最小的节点,那么不需要继续操作
  • 如果进行了节点交换,那么对换下来的节点递归进行heapify

具体实现也不难,需要多注意节点越界即可。

public void heapify(int[] nums,int n, int len) {
   

        /**
         * heapify操作
         * nums表示当前堆
         * n:对下标为n的节点做heapify操作
         * len:堆中元素的个数
         */

        if(n>=len) return;

        //找到两个孩子节点
        int c1 = n*2 + 1;
        int c2 = n*2 + 2;

        //找到最小的元素并且换到堆顶
        int min = n;
        //注意孩子节点的下标不要越界
        if((c1 < len) && (nums[c1] < nums[min])) {
   
            min = c1;
            //System.out.println(nums[0]);
        }
        if((c2 < len) && (nums[c2] < nums[min])) {
   
            min = c2;
            //System.out.println(nums[0]);
        }

        //换好元素之后,再对被换下来的位置进行heapify,
        //一直递归往下,直到遇到一个符合小顶堆的子树为止
        if(min != n) {
   
            swap(nums,min,n);
            heapify(nums, min, len);
        }
    }
heapInitial(int[] nums, int n);

由于初始数组处于乱序的状态,所以需要对其进行初始化,先建立一个小根堆。我们只需要从最后一个非叶节点,自底向上一次进行heapify即可建立一个小根堆。

public void heapInitial(int[] nums,int n) {
   

        /**
         * 对乱序的数组进行堆的创建:
         * 从最后一个非叶节点开始,
         * 从下往上对每个节点都进行一次heapify
         */

        //最后一个非叶节点既是最后一个节点的父亲节点
        int parent = (n-1)/2;

        for(int i=parent;i>=0;i--)
            heapify(nums, i, n);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值