海量数据找到最大的100个数据

前言:

海量数据指的是数据量非常大,亿级的数据。如果是 int 型数据,int型数组占4个字节的内存,1亿个int型数据就得占用近400M的内存,计算机性能差的话很难一次性读入然后排序。所以一般的靠排序来做这道题是很尴尬的。
这里用最小堆来解决,上篇讲了大顶堆的原理及大顶堆的排序,这里由于是找最大的100条数据,所以要用到小顶堆。

小顶堆的满足条件如下:

1.堆顶的元素最小
2. 左右子节点的值都大于父节点的值。

实现思路

1.用1亿条数据的前100个数据建立一个小顶堆,然后从第101条数据遍历到最后的1亿条,如果数值大于堆顶的数据,则替换堆顶的数据然后从新建立小顶堆;

实现代码如下:

public class HeapSort {
 public void buildMinHeap(int[] A) {
        for (int i = parent(A.length - 1); i >= 0; i--) {
            minHeapify(A, i, A.length);
        }
        System.out.println(".............建小根堆...............");

        for (int j = 0; j < A.length; j++) {
            System.out.println("A[" + j + "] = " + A[j]);
        }
    }

    private void minHeapify(int[] A, int i, int heapSize) {
        int l = left(i);
        int r = right(i);
        int largest = i;
        if (l <= heapSize - 1 && A[l] < A[i])
            largest = l;
        if (r <= heapSize - 1 && A[r] < A[largest])
            largest = r;
        if (largest != i) {
            int temp = A[i];
            // swap
            A[i] = A[largest];
            A[largest] = temp;
            this.minHeapify(A, largest, heapSize);
        }
    }

/**
     * 找到数组最大的n个数:先是建一个n个数的小根堆,然后遍历从n到数组的大小,如果遍历的值大于堆顶的元素则替换堆顶的值,然后从堆顶开始调整最小堆
     *
     * @param arr
     * @param n
     */

    public void findKLargestValue(int[] arr, int n) {
        int[] tmp = new int[10];
        for (int i = 0; i < n; i++) {
            tmp[i] = arr[i];
        }

        System.out.println(Arrays.toString(arr));

        buildMinHeap(tmp);
        int tp = 0;
        for (int j = n; j < arr.length; j++) {
            if (arr[j] > tmp[0]) {
                tp = tmp[0];
                tmp[0] = arr[j];
                arr[j] = tp;
            }
            minHeapify(tmp, 0, tmp.length);
        }
        System.out.println(Arrays.toString(tmp));
    }

}

测试代码:

  HeapSort heapSort = new HeapSort();
  int [] B = {3, 7, 2, 11, 3, 4, 9, 2, 18, 0, 33, 109, 35, 555, 1, 6, 99, 22, 77, 5, 767, 444};
  heapSort.findKLargestValue(B, 10);

如果不了解小顶堆的可以看我的这篇文章:
大顶堆的原及即实现

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 python 中,如果要查找海量数据的中位数,可以使用 heapq 库中的函数 nsmallest() 和 nlargest()。 首先,将所有数据读入内存,然后使用 heapq.heapify() 将数据堆化。接下来,调用 nsmallest() 和 nlargest() 来获取最小的 k 个数和最大的 k 个数。最后,根据这 k 个数的大小关系,就可以得出中位数。 例如,如果 k=len(data)//2,那么中位数就是最小的 k 个数中的最大值。 这种方法的时间复杂度是 O(n log n),空间复杂度是 O(n)。 注意,如果要查找的数据量太大,无法一次性读入内存,就需要使用其他方法,例如流式计算。 ### 回答2: 对于海量数据找中位数问题,可以使用堆排序算法来解决。 首先,将海量数据分割成多个小块,每个小块可以使用快速排序算法进行排序,再将排序好的小块使用堆数据结构进行合并。 然后,使用一个最大堆和一个最小堆来存储数据最大堆保存一半较小的数据,最小堆保存一半较大的数据。具体实现方式如下: 1. 初始化最大堆和最小堆为空堆。 2. 依次读取海量数据,并根据数据的大小来决定插入最大堆还是最小堆。 - 如果最大堆的大小小于最小堆的大小,则将数据插入最大堆,并对最大堆进行调整,保证最大堆的堆顶(即最大值)小于等于最小堆的堆顶(即最小值)。 - 如果最大堆的大小大于最小堆的大小,则将数据插入最小堆,并对最小堆进行调整,保证最小堆的堆顶(即最小值)大于等于最大堆的堆顶(即最大值)。 3. 当读取完全部数据后,根据最大堆和最小堆的大小来决定中位数的位置。 - 如果最大堆的大小等于最小堆的大小,则中位数为最大堆的堆顶和最小堆的堆顶的平均值。 - 如果最大堆的大小大于最小堆的大小,则中位数为最大堆的堆顶。 - 如果最大堆的大小小于最小堆的大小,则中位数为最小堆的堆顶。 通过这种方式,不需要将全部数据加载到内存中,可以在读取数据的同时进行排序和求解中位数,从而适用于海量数据的情况。 ### 回答3: 在Python中,处理海量数据找中位数的一种常见方法是使用堆。 首先,我们需要了解中位数的概念。对于一个有序的数据集,中位数是指将数据划分为两个等长子集,左子集中的所有元素都小于等于右子集中的所有元素。如果数据集中有奇数个元素,则中位数是中间的那个元素;如果有偶数个元素,则中位数是中间两个元素的平均值。 对于海量数据,我们无法直接将其全部加载到内存中进行排序,因此需要使用堆来解决这个问题。堆是一种特殊的树形数据结构,具有以下特点:每个节点的值都大于(或小于)其子节点的值。 我们可以使用两个堆来实现,一个大根堆和一个小根堆。首先,将数据集的一半数据插入到大根堆中,将剩余的一半数据插入到小根堆中。这样可以确保大根堆中的所有元素都小于小根堆中的元素。然后,我们可以根据数据集的大小,采取不同的策略来计算中位数。 如果数据集的大小是奇数,中位数就是小根堆的堆顶元素。如果数据集的大小是偶数,中位数就是大根堆的堆顶元素和小根堆的堆顶元素的平均值。 在实际实现中,我们可以使用Python的heapq模块来操作堆。具体的步骤如下: 1. 利用heapq模块的heapify函数,将数据一半的元素插入大根堆,将剩余的一半元素插入小根堆。 2. 如果数据集的大小是奇数,直接返回小根堆的堆顶元素。 3. 如果数据集的大小是偶数,返回大根堆的堆顶元素和小根堆的堆顶元素的平均值。 对于海量数据来说,可以将数据分块读取,每次读取一部分数据,然后进行堆的操作。通过这种方式,可以有效地处理海量数据找到中位数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值