C++ 使用位运算的基数排序

C++ 使用位运算的基数排序,c++,sorting,radix,C++,Sorting,Radix,首先,这是作业,我发现另一个话题谈论同一个话题,但没有答案。问题是: 基于以下假设的按位排序:​​要排序的是编码为B位的整数(因此介于0和2B-1之间) 主要问题是如何进行这种分类。我是否应该将每个整数转换为位并进行比较? 请不要只给我一个提示或解释怎么做。 谢谢你的帮助! [编辑] 我在互联网上找到了这个脚本,但我不明白它是如何工作的: #include <cstdlib> #include <iostream> #include <string> #inc

首先,这是作业,我发现另一个话题谈论同一个话题,但没有答案。问题是:

基于以下假设的按位排序:​​要排序的是编码为B位的整数(因此介于0和2B-1之间)

主要问题是如何进行这种分类。我是否应该将每个整数转换为位并进行比较? 请不要只给我一个提示或解释怎么做。 谢谢你的帮助! [编辑] 我在互联网上找到了这个脚本,但我不明白它是如何工作的:

#include <cstdlib>
#include <iostream>
#include <string>
#include <cctype>
#include<algorithm>
#include<string>
#include <iterator>
using namespace std;

// Radix sort comparator for 32-bit two's complement integers
class radix_test
{
    const int bit; // bit position [0..31] to examine
public:
    radix_test(int offset) : bit(offset) {} // constructor

    bool operator()(int value) const // function call operator
    {
        if (bit == 31) // sign bit
            return value < 0; // negative int to left partition
        else
            return !(value & (1 << bit)); // 0 bit to left partition
    }
};

// Least significant digit radix sort
void lsd_radix_sort(int *first, int *last)
{
    for (int lsb = 0; lsb < 32; ++lsb) // least-significant-bit
    {
        std::stable_partition(first, last, radix_test(lsb));
    }
}

// Most significant digit radix sort (recursive)
void msd_radix_sort(int *first, int *last, int msb = 31)
{
    if (first != last && msb >= 0)
    {
        int *mid = std::partition(first, last, radix_test(msb));
        msb--; // decrement most-significant-bit
        msd_radix_sort(first, mid, msb); // sort left partition
        msd_radix_sort(mid, last, msb); // sort right partition
    }
}

int main(int argc, char *argv[])
{

    int data[] = { 170, 45, 75, -90, -802, 24, 2, 66 };

    lsd_radix_sort(data, data + 8);
    // msd_radix_sort(data, data + 8);

    std::copy(data, data + 8, std::ostream_iterator<int>(std::cout, " "));

    system("PAUSE");
    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
//32位2的补码整数的基数排序比较器
类基数检验
{
const int bit;//要检查的位位置[0..31]
公众:
基数测试(整数偏移量):位(偏移量){}//构造函数
布尔运算符()(int值)常量//函数调用运算符
{
if(bit==31)//符号位
返回值<0;//左分区为负int
其他的
返回!(值&(1=0)
{
int*mid=std::partition(第一个,最后一个,基数测试(msb));
msb--;//递减最高有效位
msd_基数_排序(第一,中间,msb);//排序左分区
msd_基数_排序(中间、最后、msb);//排序右分区
}
}
int main(int argc,char*argv[])
{
int data[]={170,45,75,-90,-802,24,2,66};
lsd_基数_排序(数据,数据+8);
//msd_基数_排序(数据,数据+8);
std::copy(数据,数据+8,std::ostream_迭代器(std::cout,“”);
系统(“暂停”);
返回退出成功;
}

首先,您不需要将整数转换为位,因为它已经存储为位。
int
通常是4字节,所以是32位。您可以使用位运算符访问位

这里详细显示了基数排序

此示例基于10位数进行排序

要基于位进行排序,您可以稍微更改算法,在所有位置使用2而不是10:

void radixsort(int *a, int n) {
...
  while (m / exp > 0) {
    int bucket[2] = { 0 };
    for (i = 0; i < n; i++)      bucket[a[i] / exp % 2]++;
    bucket[1] += bucket[0];
    for (i = n - 1; i >= 0; i--) b[--bucket[a[i] / exp % 2]] = a[i];
    for (i = 0; i < n; i++)      a[i] = b[i];
    exp *= 2;
...
  }
}
这将使用单个位进行排序。要使用多个位,需要使其更通用:

#define BITS 2
void radixsort(int *a, int n) {
  int i, b[MAX], m = a[0], pos = 0;
  int buckets=1<<BITS;
  int mask=buckets-1;
  for (i = 0; i < n; i++) if (a[i] > m) m = a[i];

  while ((m>>(pos*BITS)) > 0) {
    int bucket[1<<BITS] = { 0 };
    for (i = 0; i < n; i++)       bucket[(a[i]>>(pos*BITS)) & mask]++;
    for (i = 1; i < buckets; i++) bucket[i] += bucket[i - 1];
    for (i = n - 1; i >= 0; i--)  b[--bucket[(a[i]>>(pos*BITS)) & mask]] = a[i];
    for (i = 0; i < n; i++)       a[i] = b[i];
    pos++;
...
  }
}
#定义位2
无效半径排序(整数*a,整数n){
int i,b[MAX],m=a[0],pos=0;
int bucket=1>(位置*位))>0){
int bucket[1(位置*位))&掩码]+;
对于(i=1;i=0;i--)b[--bucket[(a[i]>>(pos*位))&掩码]]=a[i];
对于(i=0;i
这将使用两个位进行排序,因此4个桶用于00、01、10和11。3个位将使用8个桶(000001010 011100101110111)


您可以看到,增加位将减少传递次数,但每次传递所做的功更大。

首先,您不需要将整数转换为位,因为它已经存储为位。
int
通常是4字节,因此32位。您可以使用位运算符访问位

这里详细显示了基数排序

此示例基于10位数进行排序

要基于位进行排序,您可以稍微更改算法,在所有位置使用2而不是10:

void radixsort(int *a, int n) {
...
  while (m / exp > 0) {
    int bucket[2] = { 0 };
    for (i = 0; i < n; i++)      bucket[a[i] / exp % 2]++;
    bucket[1] += bucket[0];
    for (i = n - 1; i >= 0; i--) b[--bucket[a[i] / exp % 2]] = a[i];
    for (i = 0; i < n; i++)      a[i] = b[i];
    exp *= 2;
...
  }
}
这将使用单个位进行排序。要使用多个位,需要使其更通用:

#define BITS 2
void radixsort(int *a, int n) {
  int i, b[MAX], m = a[0], pos = 0;
  int buckets=1<<BITS;
  int mask=buckets-1;
  for (i = 0; i < n; i++) if (a[i] > m) m = a[i];

  while ((m>>(pos*BITS)) > 0) {
    int bucket[1<<BITS] = { 0 };
    for (i = 0; i < n; i++)       bucket[(a[i]>>(pos*BITS)) & mask]++;
    for (i = 1; i < buckets; i++) bucket[i] += bucket[i - 1];
    for (i = n - 1; i >= 0; i--)  b[--bucket[(a[i]>>(pos*BITS)) & mask]] = a[i];
    for (i = 0; i < n; i++)       a[i] = b[i];
    pos++;
...
  }
}
#定义位2
无效半径排序(整数*a,整数n){
int i,b[MAX],m=a[0],pos=0;
int bucket=1>(位置*位))>0){
int bucket[1(位置*位))&掩码]+;
对于(i=1;i=0;i--)b[--bucket[(a[i]>>(pos*位))&掩码]]=a[i];
对于(i=0;i
这将使用两个位进行排序,因此4个桶用于00、01、10和11。3个位将使用8个桶(000001010 011100101110111)


您可以看到,增加位将减少传递次数,但每次传递所做的功更大。

b位的无符号整数值的范围是0到2**b-1。什么是“将每个整数转换为位”甚至是什么意思?你不能只是把单词串在一起,然后希望有一个程序出来…@KerrekSB:我的意思是把一个数字转换成二进制,然后与其他二进制数字进行比较(这是一个建议,不是一个解决方案)“把一个数字转换成二进制”是什么意思意思?这也没有意义。意思是将5转换为二进制。它将是字符串等于101。例如,b位的无符号整数值的范围是0到2**b-1。什么是“将每个整数转换为位”甚至是什么意思?你不能只是把单词串在一起,然后希望有一个程序出来…@KerrekSB:我的意思是把一个数字转换成二进制,然后与其他二进制数字进行比较(这是一个建议,不是一个解决方案)“把一个数字转换成二进制”是什么意思意思是?那也没什么意义。意思是将5转换成二进制,它将是字符串,等于101。例如,我在维基百科上看过这篇文章,但我没有发现任何关于位运算的内容。我在维基百科上看过这篇文章,但我没有发现任何关于位运算的内容