数据结构-从计数排序到基数排序
2017-03-14 12:23
12 查看
一般基于比较的排序算法时间复杂度都较高,最低就是O(NlogN),想要更快的话就很难了,而计数排序则不然特定情况下计数排序有较高效率。
1. 计数排序
思路:
1)首先找出序列当中的最大和最小的数,然后通过这两个数确定一个范围,这样就可以直接建立一个范围这么大的哈希表。
2)把数对应哈希表的下标,统计次数。
3)通过哈希表,从小到大进行遍历,然后按哈希表顺序写入序列当中。
![](http://img.blog.csdn.net/20170314120142516?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzQzMTIzODY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
实现代码:
不过这有个很明显的缺点,就是当数组最大的数很大时,比如22222222,那我们岂不是要申请22222222这么多空间?比如一个数组是{1,2,22222222},这样就存在很严重的空间浪费了。
于是就有了计数排序的升级版—–基数排序。
2. 基数排序
利用多排序码实现对单个排序码排序的算法就成称为基数排序。
这里我们就用整形来比较:
思路:对数组中的数,先以个位大小进行排序再十位…等;
![](http://img.blog.csdn.net/20170314121610553?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzQzMTIzODY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
注意尽量不要太大基数
1. 计数排序
思路:
1)首先找出序列当中的最大和最小的数,然后通过这两个数确定一个范围,这样就可以直接建立一个范围这么大的哈希表。
2)把数对应哈希表的下标,统计次数。
3)通过哈希表,从小到大进行遍历,然后按哈希表顺序写入序列当中。
实现代码:
using namespace std; template<class T=int> void CountSort(T* arr, int size) { T max = arr[0]; T min = arr[0]; for (int i = 0; i < size; ++i) { if (arr[i] < min) min = arr[i]; if (arr[i] > max) max = arr[i]; } int num = max - min + 1; T* tmp = new T[num]; memset(tmp, 0,num*sizeof(T)); for (int i = 0; i < size; ++i) { tmp[arr[i] - min]++; } int index = 0; for (int i = 0; i < num; i++) { while (tmp[i]--) { arr[index] = i + min; } } delete[] tmp; } void Counttest() { int arr[] = { 1,12,4,7,6,8,8,3}; CountSort(arr, si`` eof(arr) / sizeof(arr[0])); }
不过这有个很明显的缺点,就是当数组最大的数很大时,比如22222222,那我们岂不是要申请22222222这么多空间?比如一个数组是{1,2,22222222},这样就存在很严重的空间浪费了。
于是就有了计数排序的升级版—–基数排序。
2. 基数排序
利用多排序码实现对单个排序码排序的算法就成称为基数排序。
这里我们就用整形来比较:
思路:对数组中的数,先以个位大小进行排序再十位…等;
#include<iostream> using namespace std; template<class T=int> int GetMax(T* arr,int size) { int n = 1; int base = 10; for (int i = 0; i < size; ++i) { while (arr[i]>=base) { n++; base *= 10; } } return n; } template<class T> void RadixSort(T* arr, int size) { int n = GetMax(arr, size); int count[10] = { 0 }; int pos[10] = { 0 }; int base = 1; T* tmp = new T[size]; while (n--) { memset(count, 0, sizeof(T)*10); for (int i = 0; i < size; ++i) { count[(arr[i]/base) % 10]++;//注意这里相当于除base再模10 } pos[0] = 0; for (int i = 1; i < 10; ++i) { pos[i] = count[i-1] + pos[i - 1]; } for (int i = 0; i < size; ++i) { int ret = (arr[i]/base) %10; tmp[pos[ret]++] = arr[i]; count[ret]--; } for (int i = 0; i < size; ++i) { arr[i] = tmp[i]; } base *= 10; } delete[] tmp; } void Radixtest() { int arr[] = { 22,31,44,56,77,82,43,26 }; RadixSort(arr, sizeof(arr) / sizeof(arr[0])); }
注意尽量不要太大基数
相关文章推荐
- 数据结构系列笔记---系统导图
- 《数据结构》实验二: 线性表实验
- 数据结构-前缀、中缀、后缀表达式
- java 数据结构--链式表
- C#数据结构学习--数据结构基础知识
- 面向自己的数据结构题库
- 数据结构之线段树
- 数据结构:二叉树的定义与存储
- 初学数据结构的心得
- 数据结构 第三章
- 数据结构:二叉树
- 数据结构-链表-多项式的相乘和相加
- 选正确数据结构,莫轻信Java Hash Table
- redis数据结构HyperLogLog
- Linux内核之数据结构--队列
- 数据结构和算法关系
- 可视化的数据结构和算法
- 【数据结构和算法】【栈】顺序栈的代码实现
- 锁无关的数据结构与Hazard指针——操纵有限的资源
- 共同学习Java源代码-数据结构-HashMap(十)