博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
桶排序和计数排序
阅读量:4638 次
发布时间:2019-06-09

本文共 2188 字,大约阅读时间需要 7 分钟。

突然想自己写个桶排序,然后做课后题又发现了计数排序,觉得挺有趣的。不过书上都没有给代码,所以就自己写了一下代码,超级烂0 0下面先简单介绍下这两种排序

桶排序

桶排序,就是根据散列的思想进行数据的排序。假设有M个桶,采用最简单的hash(key)=key,这样无需比较,就可以把数存入相应的桶中。针对冲突排解问题,此时查找链的方式显然不再适用,采用独立链法,把每个桶以链表的形式存储雷同元素,定义相同元素的偏序,这样能实现排序的稳定性。桶排序完全采用了简单的哈希策略,是比较容易理解的。同时,完全摒弃了CBA式的方式,从而可以突破复杂度O(nlogn)的界限。通过空间换时间的策略,可以达到O(n)的时间复杂度,代价是O(M+N)的额外空间。下面是对于整型数组的桶排序,代码很烂我也没有改,已经测试过:

1 struct node  2 { 3     node(int v = 0, node* s = NULL) :value(v), succ(s) {} 4     int value; 5     node* succ; 6 }; 7 void insert(node &a, int b)//b插入到a后面 8 { 9     node* t = new node(b);10     if (a.succ) t->succ = a.succ;11     a.succ = t;12 }13 node* bucketSort(int* A, int n, int k)//数的范围为[0,k)14 {15     node* bucket = new node[k]();16     for (int i = 0; i < n; i++)17         insert(bucket[A[i]],A[i]);18     return bucket;19 }20 void show(node a)21 {22     while (a.succ)23     {24         a = *(a.succ);//第一个节点作为哨兵不输出25         cout << a.value << " ";26     }27 }28 int main()29 {30     int A[15] = { 2,0,1,3,3,0,1,9,7,7,15,11,13,12,10};31     node* p = bucketSort(A, 15, 16);32     for (int i = 0; i < 16; i++)33         show(p[i]);34     system("pause");35     return 0;36 }

下面有测试例子,已经经过了测试,不过这里仅把排序的结果存入了一个申请空间的列表然后输出,没有进行释放的操作,也没有存入原数组或者另外一个数组0 0看具体的要求可以改动

计数排序

计数排序的基本策略,基于这样的事实:一个有序序列,元素m的秩,应当等于序列中全部元素中,小于等于m的元素数量。所以计数排序算法可以归纳如下:遍历序列,对于每个元素,再遍历整个序列,用一个额外的数组进行计数。不难看出,时间复杂度为O(n^2)。显然,无法接受这样的复杂度。

可以考虑用散列的方法来降低复杂度。同样,对于[0,k)的元素,选取M个桶,假设元素数量为n,先遍历序列,用桶数组进行计数。随后,每一个后面的桶的计数=前面桶的数量+它自身的计数。这样,每个桶的数字-1就等于桶对应元素的秩。同时,也可以处理相同元素的问题,因为当元素存在其他因素的偏序时,数字也加在了桶数组的计数中,桶数组只需要从后向前输出,就可以维持这种偏序。实现代码如下:

1 /*计数排序*/ 2 int* countSort(int* A,int k,int n)//[0,k)范围内n个数 3 { 4     int* tmp = new int[k]; 5     int* s = new int[n]; 6     memset(tmp, 0, sizeof(int) * k); 7     for (int i = 0; i < n; i++)//原始数组中的计数 8         tmp[A[i]]++; 9     for (int i = 0; i < k - 1; i++)//记录不大于该数的数字个数10         tmp[i + 1] += tmp[i];11     for (int i = n - 1; i >= 0; i--)//逆序输出12         s[--tmp[A[i]]] = A[i];//计数哈希数组-1即为应当对应的秩,用原数组的数赋值13     delete[] tmp;14     return s;15 }

代码已经经过了测试。可以看到,只需要两趟原数组遍历,一趟桶数组遍历即可完成,时间复杂度为O(M+n)。同样,辅助空间为桶数组,空间复杂度为O(M)。不难看出,计数排序适用的最合适情况,是M远小于n的时候,即数据较多而范围不大。此时,时间复杂度仅为O(n)。

转载于:https://www.cnblogs.com/lustar/p/7308089.html

你可能感兴趣的文章
PComm串口开发
查看>>
git命令详解
查看>>
C++函数声明后面加throw()的作用
查看>>
XA 事务
查看>>
C++ 模板元编程 学习笔记
查看>>
静态联编与动态联编
查看>>
虚函数本质
查看>>
异质链表
查看>>
linux 学习笔记二
查看>>
linux 学习笔记一
查看>>
linux 学习笔记四
查看>>
linux 学习笔记三
查看>>
Spring Boot浅谈(是什么/能干什么/优点和不足)
查看>>
关于JDK和eclipse的安装和汉化
查看>>
PostgreSQL-6-数据分组
查看>>
asyncio的简单了解
查看>>
2019暑假实习
查看>>
WebBrowser IE Version
查看>>
hdu 1992
查看>>
ADO.NET的ORACLE数据库操作
查看>>