大数据排序的几种方法

在秋招的笔试中遇到过好几次大数据量排序的问题,今天又在编程珠玑上看到了类似的问题,通过以前的一些积累,写几点我对大数据排序的几种方法的一些见解。

位图法

位图法是我在编程珠玑上看到的一种比较新颖的方法,思路比较巧妙效率也很高。
使用场景举例:对2G的数据量进行排序,这是基本要求。
数据:1、每个数据不大于8亿;2、数据类型位int;3、每个数据最多重复一次。
内存:最多用200M的内存进行操作。
首先对占用的内存进行判断,每个数据不大于8亿,那么8亿是一个什么概念呢。
**1 byte = 8 bit(位)
1024 byte = 8*1024 bit = 1k
1024 k = 8*1024*1024 bit = 1M = 8388608 bit**
也就是1M=8388608位
而位图法的基本思想就是利用一位代表一个数字,例如3位上为1,则说明3在数据中出现过,若为0,则说明3在数据中没有出现过。所以当题目中出现每个数据最多重复一次这个条件时,我们可以考虑使用位图法来进行大数据排序。
那么假如使用位图法来进行这题的排序,内存占用多少呢。由题目知道每个数据不大于8亿,那么我们就需要8亿位,占用800000000/8388608=95M的空间,满足最多使用200M内存进行操作的条件,这也是这题能够使用位图法来解决的一个基础。

堆排序法

堆排序是4种平均时间复杂度为nlogn的排序方法之一,其优点在于当求M个数中的前n个最大数,和最小数的时候性能极好。所以当从海量数据中要找出前m个最大值或最小值,而对其他值没有要求时,使用堆排序法效果很好。
使用场景:从1亿个整数里找出100个最大的数
步骤:
1.读取前100个数字,建立最大值堆。(这里采用堆排序将空间复杂度讲得很低,要排序1亿个数,但一次性只需读取100个数字,或者设置其他基数,不需要1次性读完所有数据,降低对内存要求)
2、依次读取余下的数,与最大值堆作比较,维持最大值堆。可以每次读取的数量为一个磁盘页面,将每个页面的数据依次进堆比较,这样节省IO时间。
3.将堆进行排序,即可得到100个有序最大值。
堆排序是一种常见的算法,但了解其的使用场景能够帮助我们更好的理解它。

“`
public abstract class HeapSort {
public abstract boolean compare(E value1, E value2);//value1小于value2则返回true

public boolean heapSort(List<E> list){//排序  
    return heapSort(list, list.size());  
}  

public boolean heapSort(List<E> list, int n){  
    if(null == list || 0 == list.size()){  
        return false;  
    }  
    if(!heapCreate(list, n)){  
        return false;  
    }  
    for(int i = n; i > 0; --i){  
        swap(list, 0, i - 1);  
        heapAdjust(list, 0, i - 1);  
    }  
    return true;  
}  

public boolean heapCreate(List<E> list, int length){ //创建小根堆  
    if(null == list || 0 == list.size()){  
        return false;  
    }  
    for(int i = (length / 2 - 1); i >= 0; --i){  
        if(!heapAdjust(list, i, length)){  
            return false;  
        }  
    }  
    return true;  
}  

public boolean heapAdjust(List<E> list, int middle, int length){//调整堆,使其满足小根堆的条件  
    if(null == list || 0 == list.size()){  
        return false;  
    }  
    E temp = list.get(middle);  
    for(int i = (2 * middle + 1); i < length; i *= 2){  
        if(i < (length - 1) && !this.compare(list.get(i), list.get(i + 1))){  
            ++i;  
        }  
        if(this.compare(temp,list.get(i))){  
            break;  
        }  
        list.set(middle, list.get(i));  
        middle = i;  
    }  
    list.set(middle, temp);  
    return true;  
}  

public void swap(List<E> list, int i, int j){//数据交换  
    E temp = list.get(i);  
    list.set(i, list.get(j));  
    list.set(j, temp);  
}  

}

较为通用的分治策略

分治策略师对常见复杂问题的一种万能的解决方法,虽然很多情况下,分治策略的解法都不是最优解,但是其通用性很强。
分治法的核心就是将一个复杂的问题通过分解抽象成若干个简单的问题。
应用场景:10G的数据,在2G内存的单台机器上排序的算法
我的想法,这个场景既没有介绍数据是否有重复,也没有给出数据的范围,也不是求最大的个数。而通过分治虽然可能需要的io次数很多,但是对解决这个问题还是具有一定的可行性的。
步骤:
1、从大数据中抽取样本,将需要排序的数据切分为多个样本数大致相等的区间,例如:1-100,101-300…
2、将大数据文件切分为多个小数据文件,这里要考虑IO次数和硬件资源问题,例如可将小数据文件数设定为1G(要预留内存给执行时的程序使用)
3、使用最优的算法对小数据文件的数据进行排序,将排序结果按照步骤1划分的区间进行存储
4、对各个数据区间内的排序结果文件进行处理,最终每个区间得到一个排序结果的文件
5、将各个区间的排序结果合并.
通过分治将大数据变成小数据进行处理,再合并。

以上是个人关于大数据排序算法的一些想法和总结,总结了这么多算法,我觉得遇到真正的大数据量的数据pb级别的数据,还是别在一台机器上处理了,哈哈哈!

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 大数据集合的排序常用的算法有以下几种: 1. 快速排序(QuickSort):是一种分治算法,通过递归不断把数据分成两个子集并对它们分别排序,最终得到有序数列。 2. 归并排序(MergeSort):也是一种分治算法,通过递归不断把数据分成两个子集,并对它们分别排序,最终通过归并两个子集得到有序数列。 3. 堆排序(HeapSort):是一种选择排序,通过建立大根堆或小根堆不断地找出最大(最小)的元素放到最后,得到有序数列。 4. 计数排序(CountingSort):是一种非比较排序算法,通过统计每个数值出现的次数来实现排序。 这些算法的具体适用情况及优劣势可以根据具体问题进行选择。 ### 回答2: 大数据集合排序可以使用多种算法,常见的有快速排序、归并排序和堆排序。 1. 快速排序是一种高效的排序算法,它通过选择一个元素作为基准,将集合分成两个子集,并对子集进行递归排序。快速排序具有较好的平均和最坏情况下的性能,时间复杂度为O(nlogn)。 2. 归并排序是将集合划分为两个有序的子集,然后递归地将子集排序,并将两个有序子集合并成一个有序集合。归并排序具有稳定性和较好的最坏情况下的性能,时间复杂度为O(nlogn)。 3. 堆排序是通过构建一个最大堆或最小堆来排序集合。最大堆的根节点是集合中最大的元素,可以将其移动到最后一个位置,然后重新调整堆,得到次大元素。重复这个过程,直到集合有序。堆排序具有较好的最坏情况下的性能,时间复杂度为O(nlogn)。 以上是常见的算法,选择哪种算法取决于数据集的特点、排序要求以及性能要求。此外,还有其他算法如计数排序、基数排序和桶排序等,它们也可以用于大数据集合的排序。 ### 回答3: 大数据集合排序通常使用的算法是外部排序算法,其中最常用的是归并排序算法。 归并排序算法将数据集合划分为若干个较小的子集合,对每个子集合进行内部排序,然后将这些有序的子集合合并起来得到一个完整的有序集合。在大数据集合排序中,由于数据量巨大无法直接载入内存,归并排序算法可以通过分批次处理数据,将数据分为较小的块,分别对每个块进行排序,之后再进行合并操作。归并排序算法的特点是稳定、适用于大规模数据集合的排序,并且具有较好的性能。 具体步骤如下: 1. 将大数据集合划分为适当大小的小块,每个小块可以载入内存进行内部排序。 2. 对每个小块使用内部排序算法(如快速排序、堆排序等)进行排序,得到有序的小块。 3. 依次将排序好的小块进行合并,采用归并排序算法的合并操作,得到一个完整有序的大数据集合。 归并排序算法的优势是可以处理大规模数据集合,并且具有较好的稳定性和扩展性,但由于需要多次磁盘读取和写入操作,速度相对较慢。因此,在实际应用中,还可以根据具体情况选择其他适合大数据排序的算法,例如外部快速排序、外部堆排序等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值