排序算法总结(二)基数排序
2013-09-08 22:31
295 查看
前文介绍过计数排序,虽然其时间复杂度为O(n),但是其辅助空间需求较大,对于一个待排序正数数组A其所需辅助空间为max(A),当A中数值较大时辅助空间难以接受。下面介绍一种在计数排序基础之上改进的排序算法基数排序,其时间复杂度为O(1),并且只消耗10个辅助空间。
基数排序原理:
假定A={319,456,657,656,436,920,359}我们可以按照如下规则排序:
先按照百位数字排序(百位数字小的肯定小,如果百位相同则看十位,如果十位相同则看个位)得到:
319,359,456,436,657,656,920
然后对于百位相同的按照十位排序得到:
319,359,436,456,657,656,920
然后对于十位相同的按照个位排序得到:
319,359,436,456,656,657,920
数组完成排序。
从高位排序易于理解但是程序实现起来困难(是个树形结构),下面我们从低位开始排序,这样编码方便,但是不好理解。大家可以想想,如果每次排序都是稳定的,先按照个位排好,然后排十位,如果不看百位,仅仅将其看成2位数,按照十位排序后除去百位后的2位数是有序的(由于排序是稳定的,在个位已经有序的情况下,如果十位数字相同则相对位置不发生改变,也就不会影响整体的有序性),然后排好百位,这样整个数组有序,相当于执行了d次(d为数字位数)计数排序,所以其时间复杂度为O(n)。
算法稳定性:基数排序是稳定的。
参考代码:
基数排序原理:
假定A={319,456,657,656,436,920,359}我们可以按照如下规则排序:
先按照百位数字排序(百位数字小的肯定小,如果百位相同则看十位,如果十位相同则看个位)得到:
319,359,456,436,657,656,920
然后对于百位相同的按照十位排序得到:
319,359,436,456,657,656,920
然后对于十位相同的按照个位排序得到:
319,359,436,456,656,657,920
数组完成排序。
从高位排序易于理解但是程序实现起来困难(是个树形结构),下面我们从低位开始排序,这样编码方便,但是不好理解。大家可以想想,如果每次排序都是稳定的,先按照个位排好,然后排十位,如果不看百位,仅仅将其看成2位数,按照十位排序后除去百位后的2位数是有序的(由于排序是稳定的,在个位已经有序的情况下,如果十位数字相同则相对位置不发生改变,也就不会影响整体的有序性),然后排好百位,这样整个数组有序,相当于执行了d次(d为数字位数)计数排序,所以其时间复杂度为O(n)。
算法稳定性:基数排序是稳定的。
参考代码:
#include <iostream> #include <string> using namespace std; void RadixSort(int *input,int *output,int length,int d,int type); int GetNum(int num,int pos); void main() { int a[]={319,456,657,656,436,920,359}; int b[7]; int i; RadixSort(a,b,7,3,0); for (i=0;i<7;i++) { cout <<b[i]<<" "; } cout << endl; } void RadixSort(int *input,int *output,int length,int d,int type) { int i,j; int tmp[10]; for(j=0;j<d;j++) //分别按照个位、十位、百位数字进行计数排序 { for (i=0;i<10;i++) { tmp[i]=0; } for (i=0;i<length;i++) { tmp[GetNum(input[i],j+1)]++; //提取某位数字 } for (i=1;i<10;i++) { tmp[i]=tmp[i]+tmp[i-1]; //计算<=s中某元素的变量个数 } for (i=length-1;i>=0;i--) { if (0 == type) //正序 { output[tmp[GetNum(input[i],j+1)]-1]=input[i]; tmp[GetNum(input[i],j+1)]--; } else if (1 == type) //逆序 { output[length-tmp[GetNum(input[i],j+1)]]=input[i]; tmp[GetNum(input[i],j+1)]--; } } memcpy(input,output,length*4); } } int GetNum(int num,int pos) { int i,res; for (i=0;i<pos;i++) { res=num%10; num=num/10; } return res; }
相关文章推荐
- 程序猿找工作必练内功:排序算法大总结(五)——线性时间排序算法(计数排序,基数排序,桶排序)
- 排序算法总结(4)——归并排序、基数排序
- 排序算法总结之基数排序 Radix sort
- Java排序算法总结之(五)—— 基数排序
- 常见的五类排序算法图解和实现(多关键字排序:基数排序以及各个排序算法的总结)
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- Java排序算法以及算法改进总结(计数排序、基数排序、桶排序)
- 常用排序算法总结8一一基数排序
- Java排序算法总结(八):基数排序
- 程序员必须掌握的8种排序算法(八):基数排序
- 排序算法总结(六)归并排序
- 排序算法总结(2)--插入排序
- 无聊时总结总结算法之09基数排序
- 16 - 12 - 18 十大排序算法总结(三) 之 归并排序
- 排序总结之基数排序
- 排序算法之基数排序
- 经典排序算法 - 基数排序Radix sort
- 排序算法(八):基数排序
- 基数排序!一种美妙实用高效的排序算法!
- 经典排序算法 - 基数排序Radix sort