被搜索引擎坑惨的C++桶排序

匿名 (未验证) 提交于 2019-12-03 00:22:01

桶排序这个算法时,瞬间就被它可爱的名字给Q到,正好我看的一本C++书上有道桶排序的题目,费了一番功夫后解决了这道题,于是,就去百度,想看看大神们的桶排序算法是怎样写的,结果……搜索引擎把我坑惨了,如下图:

搜索到的前n条介绍,都很令人失望,我把他们的代码亲自跑了一遍,都是只能对10以内的数据排序???心里一万个mmp,如果真是这样,那还要桶排序干嘛?

我并不清楚正宗的桶排序到底是什么样子的,但我按照书上的题目,实现了一个功能还算强大的桶排序,由于我将数据储存为string类型,所以可以对很大的数排序,至于这个数到底有多大,那要看string类型数据的长度了(我又手贱百度了一下,好像这个数大到形容不出来……)。

书上的原题是这样的(我感觉这道题已经把桶排序介绍的很到位了,比百度上的各种解释都要清楚):
桶排序(bucket sort)从一个一维的待排序的正整数数组和一个二维整数数组开始,其中,二维数组的行下标是从0到9,列下标时从0到n-1,n时一位数组中待排序值的个数。这个二维数组的每一行都称为一个桶。编写一个函数bucketSort,它采用一个整数数组和该数组的大小作为参数,并执行以下操作:
a) 对于一位数组的每一个值,根据值的个位数,将其放到桶数组的各行中。例如,97放在第7行,3放在第3行,100放在第0行。这称为“分布过程”。
b) 在桶数组中逐行循环遍历 ,并把值复制回原始数组。这称为“收集过程”。上述值在一位数组中的新次序是100,3,97。
c) 对随后的每个数位(十位,百位,千位等)重复这一过程。
在第二遍排序时,100放在第0行,3放在第0行(因为3没有个位),97放在第9行。收集过程之后,一维数组中值的顺序为100,3,97。在第三遍排序时,100放在第1行,3放在第0行,97放在第0行(在3之后)。在最后一次收集过程之后,原始数组就是有序的了。

不扯废话了,直接上代码:

# include <iostream> using namespace std;  //将字符串中指定下标处的字符转换为对应的数字 int stringToInt( string str, int sub ) {     return ((int)str[sub] - 48); }  //桶排序,参数len:待排序数据的个数 void bucketSort( string str[], int len ) {     string arr2[10][len];  //桶      int i;     int j;      //初始化桶     for ( i = 0; i < 10; i++) {         for ( j = 0; j < len; j++) {             arr2[i][j] = "-1";         }     }      int subStr;  //字符串中,指定下标处的字符所对应的数字     int iSub;  //下标     int flag = 1;  //记录循环次数     int maxLength = 0;  //待排序的一组数中,最长的数的长度      //找出桶中最大数的长度(用于判断循环是否需要结束)     for ( i = 0; i < len; i++) {         if (str[i].length() > maxLength) {             maxLength = str[i].length();         }     }      //排序     while(1) {         for ( i = 0; i < len; i++) {             iSub = str[i].length() - flag;  //下标(初始取最后一个下标)              if (iSub < 0) {  //下标为负的时候,令下标处的字符对应的数字为0                 subStr = 0;             } else {                 subStr = stringToInt(str[i], iSub);  //将iSub下标处的字符,转换为对应的数字             }              //将数字存入对应的桶中             for ( j = 0; j < len; j++) {                 if (arr2[subStr][j] == "-1") {                     arr2[subStr][j] = str[i];                      break;                 }             }         }          int counter = 0;  //计数器         //收集桶中的数字         for ( i = 0; i < 10; i++) {             for ( j = 0; j < len; j++) {                 if (arr2[i][j] != "-1") {                     str[counter] = arr2[i][j];                      counter += 1;                 }             }         }          flag += 1;          //循环maxLength次后,排序结束,此时flag值为maxLength + 1         if (flag == (maxLength + 1)) {             //打印结果             for ( i = 0; i < len; i++) {                 cout << str[i] << " ";             }             cout << endl;              return;         }          //重置桶         for ( i = 0; i < 10; i++) {             for ( j = 0; j < len; j++) {                 arr2[i][j] = "-1";             }         }     } }  int main() {     string arr1[15] = { "33", "28", "0", "1", "436", "6", "100", "9", "211", "223", "95", "20", "560", "16", "999" };     string arr2[10] = { "1", "28", "33", "100", "9", "223", "95", "560", "16", "999" };     string arr3[5] = { "436", "6", "20", "99", "211" };     string arr4[5] = { "10000", "6000000", "0", "999999", "11111111" };      bucketSort(arr1, 15);  //1 6 9 16 20 28 33 95 99 100 211 223 436 560 999     bucketSort(arr2, 10);  //1 9 16 28 33 95 100 223 560 999     bucketSort(arr3, 5);  //6 20 99 211 436     bucketSort(arr4, 5);  //0 10000 999999 6000000 11111111      return 0; }

编译器:CodeBlocks

对代码的补充说明:
string类型一是因为能对很大很大的数排序,二是取某个数的某个位上的数比较方便。
第四组测试数据可以看出,对很大很大的数排序完全没问题。


代码思路简单,注释也比较详细,看我这篇博客的大佬们肯定都能看懂滴,就不再赘述了。

结语:因水平有限,文章有错误或者不足,欢迎评论,希望轻拍,一起进步哦!

END!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!