基数排序
来源:互联网 发布:淘宝显示全球购的标志 编辑:程序博客网 时间:2024/06/03 13:04
counting_sort
//此算法是稳定的,但是,不是原址排序,k很大时,也是不适合的void counting_sort(int *arr, int *B, int length, int k){//-----O(length+k) int C[k + 1]; for (int i = 0; i < k + 1; i++)//O(k) C[i] = 0; for (int i = 0; i < length; i++)//O(length) C[arr[i]]++; for (int i = 1; i < k + 1; i++) C[i] = C[i] + C[i - 1]; /*对于每一个arr[i]中的元素来说 C[arr[i]]中存储了 <= arr[i]的元素的个数 */ for (int i = length; i > 0; i--){//从后往前 B[C[arr[i]]] = arr[i];//arr[i]的位置应该是C[arr[i]] C[arr[i]]--;//减一,下一个与arr[i]相同的元素会放在前一个位置 //因为是从后往前,因此它是稳定的原本元素的顺序不变 }}
插入排序和归并排序也是稳定的
堆排和快排是不稳定的
基数排序
从最低有效位开始,根据改位大小排序,对全部位数进行排完序,就完成了 基数排序。
void radix_sort(int *arr, int d, int length){ for(int i = 0; i < d; i++) //use a stable sort to sort array A on digit i;}
可任意选择一个稳定的排序算法
当对于counting_sort来说参数k不大时,可选择counting_sort
基数排序复杂度:O(d(n+k))
void get_sort_data(int *arr, int *sort_data, int length, int radix){ if(radix == 1) for (int i = 0; i < length; i++)//-----------O(length) sort_data[i] = (arr[i] % 100) % 10; else if(radix == 2) for (int i = 0; i < length; i++) sort_data[i] = (arr[i] % 100) / 10; else if(radix == 3) for (int i = 0; i < length; i++) sort_data[i] = arr[i] / 100;}void counting_sort_radix(int *in, int *B, int length, int k, int radix){//-----O(k+length) int arr[length]; for (int i = 0; i < length; i++)//------------O(length) arr[i] = in[i]; get_sort_data(in, arr, length, radix);//--------O(length) int C[k + 1]; for (int i = 0; i < k + 1; i++)//-------------O(k) C[i] = 0; for (int i = 0; i < length; i++)//--------O(length) C[arr[i]]++; for (int i = 1; i < k + 1; i++)//-------------O(k) C[i] = C[i] + C[i - 1]; /*对于每一个arr[i]中的元素来说 C[arr[i]]中存储了 <= arr[i]的元素的个数 */ for (int i = length-1; i >= 0; i--){//从后往前------------------O(length) B[C[arr[i]]] = in[i];//arr[i]的位置应该是C[arr[i]] C[arr[i]]--;//减一,下一个与arr[i]相同的元素会放在前一个位置 //因为是从后往前,因此它是稳定的原本元素的顺序不变 }}void radix_sort(int *arr, int d, int length){//-------------O(d*(k+length)) int temp[length]; for (int i = 0; i < length; i++)//--------O(length) temp[i] = arr[i]; int ret[length+1]; for (int i = 0; i < d; i++){//----------O(d) * O(k+length) = O(d*(k+length)) counting_sort_radix(temp, ret, length, 9, i+1);//---------O(k+length) for (int i = 1; i <= length;i++)//----O(length) temp[i-1] = ret[i]; } for (int i = 0; i < length; i++)//-----O(length) arr[i] = temp[i];}void main_counting_sort(){ // int arr[30] = {2, 3, 20, 5, 6, 6, 19, 10, 20, 5, 3, 20}; int arr[30] = {21, 12, 42, 123, 124, 42, 12, 32, 16, 86, 456, 33, 237, 886, 764}; algorithms::radix_sort(arr, 3, 15); for (size_t i = 0; i < 15; i++) cout << arr[i] << " "; cout << endl;}
算法导论习题8.3-3
证明基数排序是正确的,并且指出在什么地方基数排序需要内层的排序是稳定的?
证明:数学归纳法
d = 1时,只有一个数字,利用内层排序,排完之后就是结果
假设在d-1时已经排完序,
现证在d时排完序之后结果是正确的:
在d-1排完之后,数组中的顺序依据第d-1位,
考虑xd和yd,分别属于第d位的两个数字,
若 xd > yd,则xd位于yd之后
若xd < yd, 则xd位于yd之前
若xd = yd,则根据内层算法确定,相同的元素的位置,这里的counting_sort是稳定的,
所以其相对位置保持不变,其大小顺序就是d-1位上的顺序
且从d=1时是正确的,所以对整个排序是正确的
当某一位上的两个值相同时需要内层算法是稳定的
算法导论8.3-4
说明在O(n)时间内,对n^3-1区间内的n个整数进行排序。
答案:d = 3, 每一位范围从0 - n-1;
复杂度:调用三次counting_sort(arr, B, n, n),每一次复杂度为O(n+n)
因此复杂度为O(n)
阅读全文
0 0
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 个人博客
- IntelliJ IDEA windows与mac下常用快捷键
- Android Studio gradle 提示"unable to find valid certification"的解决办法
- linux常用命令
- $.ajax()的基本语法
- 基数排序
- Django 创建第一个项目
- 基于kubernetes1.5.2集群部署DashBoard
- Elasticsearch5.3.1 IK分词,同义词/联想搜索设置
- CentOS7搭建NAS,包括NFS、ISCSI
- 记录一篇生动形象的傅里叶变换
- Codeforces Round #441 div2 C. Classroom Watch
- ftp服务器的搭建
- servlet、spring mvc、struts2 、play的http请求处理