赞
踩
基数排序是基于桶排序的一种排序,
基数排序可以看作桶排序。
桶排序是按值域划分桶,
基数排序是按位数划分桶。
分类(LSD和MSD):
① 最低位优先LSD法:先从最低位开始排序,再对次低位排序,直到对最高位排序后得到一个有序序列。
② 最高位优先MSD法:先从最高位开始排序,再对次高位排序,直到对最低位排序后得到一个有序序列。
【基本思想】
分配+收集
① 基数排序也叫桶排序或箱排序:设置若干个箱子,将关键字为的记录放入第k个箱子,然后在按序号将非空的连接。
② 要求箱子个数是有范围的,例如:数字是有范围的,均由0-9这十个数字组成,则只需设置十个箱子,相继按个、十、百…进行排序。
例:
(614,738,921,485,637,101,215,530,790,306)
void radixsort(int num[],int len) { int i,j,k,l,digit; int allot[10][N]; memset(allot,0,sizeof(allot)); for(i=1;i<=D;i++) { int flag=0; for(j=0;j<len;j++) { digit=getdigit(num[j],i); k=0; while(allot[digit][k]) k++; allot[digit][k]=num[j]; if(digit) flag=1; } if(!flag) break; l=0; for(j=0;j<10;j++) { k=0; while(allot[j][k]>0) { num[l++]=allot[j][k]; k++; } } memset(allot,0,sizeof(allot)); } }
时间复杂度:O(k*(n+m))
关键字:分配的标准,如按百位排序,按千位排序……
k:关键字个数,表示分配多少趟。
m:关键字取值范围为m个值,也就是桶的个数。
n:元素个数。
空间复杂度:S(n)=O(n+m)
稳定性:稳定
优点:算法效率高;
缺点:关键字的取值范围有限。
“桶排序”又称“箱排序”。
【基本思想】
桶排序是将待排序序列中处于相同值域的元素存入同一个桶中,即将一个数据表分割成许多桶,然后每个桶中的元素各自排序。它采用分治策略,是一种分布式的排序方法。
【基本步骤】
① 根据待排序序列中最大元素和最小元素的差值和映射规则,确定申请的桶个数;
② 遍历待排序序列,将每一个元素存储到对应的桶中;
③ 分别对每一个桶中元素进行排序,并存储到原序列中,获得一个已排序序列。
bool buckertSort(int array[], size_t arrLen, size_t bucketSize) { const int DEFAULT_BUCKET_SIZE = 10; if(arrLen < 2) { return true; } if (bucketSize < 1) { bucketSize = DEFAULT_BUCKET_SIZE; } // Find the scope of the array int min = array[0]; int max = array[0]; for (size_t i = 1; i < arrLen; ++i) { if (min > array[i]) { min = array[i]; } else if (max < array[i]) { max = array[i]; } } // Create buckets int **buckets = new int*[bucketSize]();//创建桶 int *bucketLen = new int[bucketSize]();//创建记录当前桶内数据个数,初始化为0 //计算桶的数据的范围,可以把它想象为把一个线段,平均分成bucketSize个小线段,小线段的长度就是bucketScope //为什么+1,大家知道min=10,max=90,其实有81个数据,如果按照(90-10)/10来分,你桶里面的数据范围只能从10到89,所以要用1补齐 int bucketScope = floor((max - min)/bucketSize) + 1; //创建桶空间,只有桶里面有空间才能放数据 for (size_t j = 0; j < bucketSize; j++) { buckets[j] = new int[arrLen](); } int bucketIndex = -1; // Put array value to buckets for (size_t k = 0; k < arrLen; ++k) { bucketIndex = floor((array[k] - min)/bucketScope); //计算数据所在桶的下标 buckets[bucketIndex][bucketLen[bucketIndex]++] = array[k];//将数据放入桶中 } // Sort value in bucket and put ordered value back to array int arrayIndex = 0; for (size_t l = 0; l < bucketSize; l++) { if (bucketLen[l] > 0) { insertSort(buckets[l], bucketLen[l]); //对桶内数据进行排序 for (size_t m = 0; m < bucketLen[l]; ++m) { array[arrayIndex++] = buckets[l][m];//将排好序的数据放回原数组 } } delete [] buckets[l]; buckets[l] = NULL; } delete [] buckets; delete [] bucketLen; return true; }
【基本思想】
若待排序序列的元素均为非负整数,且最大值为max,则分配max+1个桶,每个桶的编号(下标)就等于待排序元素的值,每个桶的元素值就是存入桶中的待排序元素个数。为了描述方便,我们将桶序列称为统计数组。
【基本步骤】
(1)根据待排序序列中最大元素值,确定申请的桶个数,并将桶全部清空;
(2)统计待排序序列中每个值为i的元素出现的次数,存入编号为i的桶;
(3)依次把数据从桶里倒出来,存储到原序列中,获得一个已排序序列。
#include<iostream> using namespace std; int main() { int arr[]={3,5,6,9,5,2,4,7}; int len=8; int count[8]={0};//9-2+1 for(int i=0;i<len;i++) { count[arr[i]]++; } for(int i=0;i<8;i++) { while(count[i]!=0) { cout<<i<<" "; count[i]--; } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。