排序8:位图排序

位图排序也称为bitmap排序,它主要用于海量数据去重和海量数据排序,假如说有10 亿个int类型且全部不相同的数据,给1G内存让你排序,你怎么排,如果全部加载到内 存中,相当于40亿个字节,大概约等于4G内存。所以全部加载到内存肯定不行,如果我 们使用位图排序的话,我们用long类型表示,一个long占用8个字节也就是64位,所以 如果我们使用位图排序的话只会占用约0.125G内存,内存占用大大减少。但位图排序有 个缺点就是数据不能有重复的,如果有重复的会覆盖掉,这也是位图能在海量数据中去 重的原因,我们看下位图排序的代码:

 public static int[] bitmapSort1(int[] arary) {
        int max = getMaxNumbit1(arary);
        int N = max / 64 + 1;
        long[] bitmap = new long[N];
        for (int i = 0; i < arary.length; i++)
            bitmap[arary[i] / 64] |= 1L << (arary[i] % 64);

        int k = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < 64; j++) {
                if ((bitmap[i] & (1L << j)) != 0) {
                    arary[k++] = i * 64 + j;
                }
            }
        }
        if (k < arary.length) {
            return Arrays.copyOfRange(arary, 0, k);
        }
        return arary;
    }

    private static int getMaxNumbit1(int[] arary) {
        int max = arary[0];
        for (int i = 1, length = arary.length; i < length; i++) {
            if (arary[i] > max) {
                max = arary[i];
            }
        }
        return max;
    }

测试一下:

int array2[] = {2, 16, 97, 13, 15, 11, 89, 7, 63, 21, 66, 8, 0};
int array3[]= bitmapSort1(array2);
System.out.println(Arrays.toString(array3));

执行结果:

 我们看到这是使用的是位表示,一个long类型占8个字节,但他可以表示64个数字,所 以内存占用会大大减少。最后有个k < array.length的判断,是因为如果有重复的数据 会覆盖掉重复的,导致数组变小。但这里面还有个问题就是不能有负数出现,如果出现 负数会报异常,我们也可以改一下让负数也可以排序,看代码。

public static int[] bitmapSort2(int[] arary) {
        int []value = getMaxNumbit2(arary);
        int N = (value[0]-value[1]) / 64 + 1;
        long[] bitmap = new long[N];

        for (int i = 0; i < arary.length; i++)
            bitmap[(arary[i]-value[1]) / 64] |= 1L << ((arary[i]-value[1]) % 64);

        int k = 0;
        int []temp=new int[arary.length];

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < 64; j++) {
                if ((bitmap[i] & (1L << j)) != 0) {
                    arary[k++] = i * 64 + j+value[1];
                }
            }
        }
        if (k < arary.length) {
            return Arrays.copyOfRange(arary, 0, k);
        }
        return arary;
    }
    
   private static int[] getMaxNumbit2(int[] arary) {
        int max = arary[0];
        int min = arary[0];
        for (int i = 1, length = arary.length; i < length; i++) {
            if (arary[i] > max) {
                max = arary[i];
            }else if(arary[i]<min){
                min=arary[i];
            }
        }
        return new int[]{max,min};
    }  

再测试一下:

 int array[] = {2, 6, 9, 3, 5, 1, -9, 7, -3, -1, -6, 8, 0};
 int array3[]= bitmapSort2(array);
 System.out.println(Arrays.toString(array3));

执行结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纵横千里,捭阖四方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值