位图排序

先说些题外话吧,本来以为blogbus修护好了,上去之后依然是错误,系统错误。靠,晕死了。既然如此,我只能弃之了,改日把东西搬过来。

进入正题:位图排序。

说实话,说到排序,我们首先想到的肯定是那些常见的排序,比如:冒泡啊,插排,选择啊,快排,甚至归并、基数排序等。这个位图排序似乎没听过啊。是的,是比较新鲜,但也很novel的一个算法。我最初见它于《编程珠玑》13章。当时只知道有个位图排序,但是具体的原理内幕,搞不懂啊。于是我查了一下详情,果然找到了一些。看我一一道来:

首先,相比以上的排序方法,位图排序明显的优点就是空时双赢啊(时间和空间)。该算法100w的非负整数只需0.125M内存,而时间复杂度则为o(n)(what? 你没搞错吧),是的,我没搞错。确实是这样。

比如N=100w个数来排序,每个int占32位,100w个数需要多少int型数呢?N/32+1,那么需要数组int array[N/32+1]就能代表N位了。

好,接下来重点:用一个整型数组 array[n] 来实现对输入数据的排序工作。具体点就是:(1)初始化,将数组的每个元素清 0;(2)插入数据并实现排序,对于输入数据 i,置 array[i] 为 1; (3)输出排序结果,如果 array[i] 为 1,就输出整数 i 

比如整数60吧,60/32=1,0%32=28,那么也就是要将array[1](供32位)的第28位置为1就表明60存在。

除以32 可使用 右移 5 位 ( i >> 5) 来实现, 对 32 取模, 可以通过 1 << ( i & 0x1f )  来实现

#define N 1000000

#define base  32

#define shift  5

#define mask 0x1f

int array[N/base+1]

void set(int i)  //置i位1

{

 array[i>>shift] |=(1<<(i&mask));

}

void clr(int i)   //i对应位置0

{

 array[i>>shift] &=~(1<<(i&mask));

}

int test(int i)//测试i对应位是否为1

{

return  array[i>>shift] &(1<<(i&mask));

}

以上是核心三项,你没输入一次,数据就已经在数组中排好序了。你可以试一下哦。

当然东西都是两面的,他好的一面也暗示了它若得一面了,说说他的局限吧:

(1)都是非负整数,(2)每个整数最多出现一次,(3)最大整数小于 N。

posted on 2011-03-24 22:40  kevinferry  阅读(450)  评论(1编辑  收藏  举报