现在的位置: 首页 > 综合 > 正文

位图数据结构

2014年01月06日 ⁄ 综合 ⁄ 共 2496字 ⁄ 字号 评论关闭

位图数据结构,就是用一块内存区域的每个比特表示一个对象的数据结构。

叫做 bitmap 或者 bitplane。

优点是速度快,内存空间占用小,能表示大范围的数据。

《Programming Pearls》里面举了一个例子,假设要对0到一千万范围内的、没有重复元素的正整数排序,

则利用位图数据结构很合适。

要使用位图数据结构,就必须熟悉位操作。

以下是已经写好的操作位图数据结构的实用函数:

#define BITS_PER_BYTE 8
#define BITS_PER_INT (BITS_PER_BYTE * 4)
// set the bit of the int specified by index to 1.
// the index is zero-based, counting from the left(the higher end)
inline void pearl_int_set(int* data, int index)
{
	int mask = 1 << (BITS_PER_INT - 1 - index);
	*data |= mask;
}

// test whether a bit of the int specified by index is 1.
// the index is zero-based, counting from the left(the higher end)
inline int pearl_int_test(int* data, int index)
{
	int mask = 1 << (BITS_PER_INT - 1 - index);
	return (*data) & mask;
}

// set a bit of the int specified by bit_index to 0.
// the index is zero-based, counting from the left(the higher end)
inline void pearl_int_clear(int *data, int bit_index)
{
	int mask = ~(1 << (BITS_PER_INT - 1 - bit_index));
	*data &= mask;
}

// get the right(lower) part of the int.
inline int pearl_int_right(int *data, int count)
{
	int mask = 1;
	while(count > 0) {
		mask = mask << 1 + 1;
	}
	return *data & mask;	
}

// get the left(upper) part of the int value
inline int pearl_int_left(int *data, int count)
{
	int mask = 1;
	count = BITS_PER_BYTE - count;
	while (count > 0) {
		mask = mask << 1 + 1;
	}

	mask = ~mask;
	return *data & mask;
}

// set a bit of the speicified memory area to 1.
// @warning this function does NOT perform error checking.
inline void pearl_set(int *bitplane, int index)
{
	int offset = index / BITS_PER_INT;
	int pos = index - offset * BITS_PER_INT;

	pearl_int_set(bitplane + offset, pos);
}

// set a bit of the specified memory area to 0.
// @warning this function does NOT perform error checking.
inline void pearl_clear(int *bitplane, int index)
{
	int offset = index / BITS_PER_INT;
	int pos = index - offset * BITS_PER_INT;

	pearl_int_clear(bitplane + offset, pos);
}

// test if a bit of the specified memory area is 1.
// @warning this function does NOT perform error checking.
inline int pearl_test(int *bitplane, int index)
{
	int offset = index / BITS_PER_INT;
	int pos = index - offset * BITS_PER_INT;

	return pearl_int_test(bitplane + offset, pos);
}


约定

所有比特的编号方法是,从低字节的高位比特位开始,第一个bit为0,最后一个bit为 n-1。

例如,假设 int arr[4] 表示一块内存区域,共16个字节,共128个比特,第1个整数 arr[0] 的高比特(从左边数,第1个字节,第1个比特)为第0个比特。

因此,上面程序与机器是大端还是小端模式无关。

图解:

编号:  |0123456------->-------

              |00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 | 00000000 |....

              |<-------------------arr[0]--------------------------->|<---------------arr[1]--------------------------------->....

用法举例:

int main(int argc, char* argv[]) {
    int* bitplane = (int*)malloc(sizeof(int)*SIZE);
    pearl_set(bitplane, n); // 0 <= n <= SIZE * 4 * 8 - 1
    if ( pearl_test(bitplane, n) ) {
        printf("bit(%d) is set\n", n);
    }
    pearl_clear(bitplane, n);
    if ( pearl_test(bitplane, n) ) {
        printf("bit(%d) is cleared\n", n);
    }
    return 0;
}

抱歉!评论已关闭.