编程珠矶学习笔记(1)--位排序

本文介绍了一种利用位操作实现高效整数排序的方法。通过定义宏和内联函数,可以快速地设置、清除和测试特定位置的位,进而实现整数的存储与检索。适用于大量整数的排序场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

个人原创,转载请注明出处,谢谢!

一、代码

#include <stdio.h>

 

#define BITSPERWORD 32

#define SHIFT 5

#define MASK 0x1F

#define N 10000000

 

int a[1 + N/BITSPERWORD];

 

inline void set_bit(int i)

{       

       a[i>>SHIFT] |=  (1<<(i & MASK));

}

 

inline void clear_bit(int i)

{       

       a[i>>SHIFT] &= ~(1<<(i & MASK));

}

 

inline int  test_bit(int i)

{

       return a[i>>SHIFT] & (1<<(i & MASK));

}

 

int main()

{     int i;

for (i = 0; i < N; i++) {

              clear_bit(i);

       }

 

       while (scanf("%d", &i) != EOF)

              set_bit(i);

 

       for (i = 0; i < N; i++) {

              if (test_bit(i)) {

                     printf("%d/n", i);

              }

       }

       return 0;

}

 

 

 

二、代码注解

#include <stdio.h>

 

/*WORDR 的位数,这里用的是int4字节32*/

#define BITSPERWORD 32

 

/*这里是每个int型的偏移量,

25次方是32,即1左移5位是32*/

#define SHIFT 5

 

/*十六进制1F,用于作掩码来计算n在某一word中位于

第几位。如计算i & MASK 等价于i %32 ,但位操作性能会更高一些*/

#define MASK 0x1F

 

#define N 10000000

 

/*N/BITSPERWORDN位需要多少个WORD,加1是向上取整,

即宁可多几位也不能少1*/

/*分配静态数组用于保存各数据位*/

int a[1 + N/BITSPERWORD];

 

/*

 *用于设置第i

 */

inline void set_bit(int i)

{       

       a[i>>SHIFT] |=  (1<<(i & MASK));

       /*

        *首先需要知道i会落在第几个word中即a[i >> SHIFT]

        *其次需要知道i在该word中应该在哪一位即 (1<<(i&MASK))

        *最后使用|运算完成置位。

        *例子:假设i=100,则i a[100 >> 5] = a[3], (1 << (100 & 31)) = (1<<4)

        *                a[3] |= (1 << 4),则置上了a[3]的第四位

        *       100= a[0 ] *32 + a[1] *32 + a[2] * 32 + a[3]4,这样当我们发现a[3]

        *       的第4位被置时,我们就可以知道100这个数存在

       */

}

 

/*

 *清位是置位的逆运算,与置位类似找到i所在的WORD,然后再

 *找到其在该WORD中的位,set相反的是它将该位取反为0,然后

 * 进行与操作

 */

inline void clear_bit(int i)

{       

       a[i>>SHIFT] &= ~(1<<(i & MASK));

}

 

/*

 *测试i位是否被置位,即找到第i位然后看该位是否为1

 *找位的过程和上面相同,然后令该位和1进行与操作

 *如果为0则没有置位,如果不为0则该位被置

 */

inline int  test_bit(int i)

{

       return a[i>>SHIFT] & (1<<(i & MASK));

}

 

int main()

{     int i;

 

       /*初始化数组,清除所有位使用memset效率会更高一些*/

       for (i = 0; i < N; i++) {

              clear_bit(i);

       }

 

       /*使用文件等输入方式,输入所有的整数*/

       while (scanf("%d", &i) != EOF)

              set_bit(i);/*置每一个整数*/

 

       /*打印出所有存在的整数*/

       for (i = 0; i < N; i++) {

              if (test_bit(i)) { /*只要该位被置说明该整数存在*/

                     printf("%d/n", i);

              }

       }

       return 0;

}

 

三、应用

举个简单的例子,如果我们有一组乱序的整数存在文件 file-data.tmp中,我们希望对其进行排序:

 

100

4

98

34

56

234

 

假设上面的程序编译后的可执行文件为 bit-sort,那么在Linux操作系统中,我们可以使用如下的方式对文件内的乱序整数进行排序:

 

% cat file-data.tmp | bit-sort

输出结果为:

 

4

34

56

98

100

234

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值