算法导论:第8章 线性时间排序__基数排序

来源:互联网 发布:淘宝拍卖业务管理规范 编辑:程序博客网 时间:2024/06/05 23:40
/*基数排序:含义:用在卡片机上的排序算法。特点:从最低位进行排序,稳定,d位数需要d趟适用:对年月日的排序引理:n个d位数,每个数有k个可能的取值,基数排序采用稳定排序。耗时O(d(n+k))  证明:共需要d趟,每趟对n个数排序,采用基数排序O(n+k),因此总共需要O(d(n+k))第一行的数n表示共有n个数字第二行为n个数输入:7329 457 657 839 436 720 355输出:329 355 436 457 657 720 839*/#include <iostream>#include <stdlib.h>#include <string.h>#include <vector>using namespace std;const int MAXSIZE = 10000;//获取数字iNum中第d位数字,如果没有肯定返回0int getDigit(int iNum,int d){int iResult;int iCount = 0;do{if(iCount == d){break;}iResult = iNum % 10;iNum = iNum / 10;iCount += 1;}while(iNum != 0);//如果还没有到达第d位,说明该数没有第d位,则直接返回0if(iCount < d){return 0;}else{return iResult;}}//计算最高位数d,123 / 10 = 12,余3,12/10=1余2,1/10=0采用除10取余直到除尽的方法int digitNum(int iNum){int iDigitNum = 0;do{iNum = iNum / 10;iDigitNum += 1;}while(iNum != 0);return iDigitNum;}void print(int* pArr , int n){for(int i = 0 ; i < n ; i++){cout << pArr[i] << " ";}}//计数排序,d表示第d趟void countSort(int* pArr,int n,int k){int* cArr = new int[k+1];int* bArr = new int[n];//初始化和计数for(int i = 0; i <= k ; i++){cArr[i] = 0;}for(int i = 0 ; i < n ; i++){cArr[ pArr[i] ] += 1;}//确定摆放位置for(int i = 1 ;i <= k ; i++){cArr[i] += cArr[i-1];}//将计数结果输入到临时数组中for(int i = n -1 ; i >= 0 ; i--){//注意位置是从0开始的,需要减1bArr[ cArr[ pArr[i] ] - 1 ] = pArr[i];//摆放位置减一,防止出现重复元素cArr[ pArr[i] ] -= 1;}//将结果写回原数组中for(int i = 0 ; i < n; i++){pArr[i] = bArr[i];}delete[] cArr;delete[] bArr;}//基数排序,共需d趟,每趟时间O(n+k),每i趟先计算出各个数字的第i个低位,然后排序,这是数位上的数字需要和原数字建立联系//最难的就是如何将数位上的数和原数字建立联系,因为计数排序肯定只能对,可以直接用就行,需要一个桶vector<>存放某一趟以某个数字结尾的数字,void radixSort(int* pArr , int n, int d){for(int i = 1 ; i <= d ; i++){//按照第i位,塞入到对应的桶中,因为0~9,所以需要10个桶vector< vector<int> > vecBucket;for(int k = 0 ; k < 10 ; k++){vector<int> vecTemp;vecBucket.push_back(vecTemp);}//分解每个数字的第i位,并按照要求塞入到桶中,并将每个数字的第i位存储到数字中int* aArr = new int[n];for(int j = 0 ; j < n ; j++){int digitNum = getDigit(pArr[j] , i);//根据第i位上的数字,塞入到桶中vecBucket[digitNum].push_back( pArr[j] );aArr[j] = digitNum;}//对其进行计数排序countSort(aArr , n , 9);//根据计数排序结果和桶中的数字,逐步取出各个数字(逆序),然后再填入到原来的数组中for(int k = n - 1 ; k >= 0 ; k--){int a = aArr[k];int num = vecBucket[a].back();pArr[k] = num;vecBucket[a].pop_back();}delete[] aArr;}print(pArr , n);}void process(){int n;//int iArr[MAXSIZE];while(cin >> n){int maxNum = -1000;int* pArr = new int[n];for(int i = 0 ; i < n; i++){cin >> pArr[i];if(pArr[i] > maxNum){maxNum = pArr[i];}}int d = digitNum(maxNum);radixSort(pArr , n, d);delete[] pArr;}}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击