排序算法之基数排序

来源:互联网 发布:python turtle函数 编辑:程序博客网 时间:2024/05/05 01:41

概述

首先从多排序码排序开始介绍基数排序。以扑克牌排序为例。每张扑克牌有两个“排序码”:花色和面值。其有序关系为:

  • 花色:<<<
  • 面值:2<3<4<5<6<7<8<9<10<J<Q<K<A

如果把所有扑克牌排成以下次序:
♣2,…,♣A,♦2,…,♦A,♥2,…,♥A,♠2,…,♠A
这就是多排序码排序。排序后形成的有序序列叫做字典有序序列。
一般情况下,假定有一个n个元素的序列V0V1...Vn1,且每个元素Vi中含有d个排序码(K1,K2,...,Kd)
实现多排序码排序有两种常用的方法:一种方法是最高位优先(Most Significant Digit first,MSD),一种方法是最低位优先(Least Significant Digit first,LSD)。

MSD基数排序

基本思想

首先根据最高位关键码K1得到若干对象组,对象组中的每个对象都有对象都有相同的关键码K1;再分别对每组中的对象根据关键码K2进行排序,按K2值的不同,再分成若干个更小的子组,子组中的对象具有相同的K1K2值;依次重复,直到对关键码Kd完成排序为止。最后,把所有子组中的对象依次连接起来,就得到一个有序的对象序列。

代码

private int radix = 10;//基数,默认十进制private void msdRadixSort(int[] a, int left, int right, int d) {    int[] auxArray = new int[a.length];// 辅助数组,存放按桶分配的结果,根据count[]预先算定各桶元素的使用位置    int[] count = new int[right-left+1];// 辅助数组,记录当处理第i位时各个元素的第i位取值为k的有多少个。    int i, j;    if (d > 0) {//位数尚未处理完        //初始化count数组        for (i = 0; i < radix; i++)            count[i] = 0;        //统计各桶元素的个数        for (i = left; i <= right; i++)            count[getDigit(a[i], d)]++;        //计算各桶元素的存放位置        for (i = 1; i < radix; i++)            count[i] = count[i] + count[i - 1];        //将待排序列中的元素按位值分配到各个桶中,存于辅助数组auxArray中        for (i = left; i <= right; i++) {            j = getDigit(a[i], d);  //取元素a[i]第d位的值            auxArray[count[j] - 1] = a[i];  //按预先计算位置存放            count[j]--;     //计数器减1        }        //从辅助数组顺序写入原数组        for (i = left, j = 0; i <= right; i++, j++)            a[i] = auxArray[j];        //按桶递归对d-1位处理        for (j = 0; j < radix - 1; j++) {            int p1 = count[j];  //取桶开始端            int p2 = count[j + 1] - 1;  //取桶结束端            if (p1 < p2 && d > 1)                msdRadixSort(a, p1, p2, d - 1);//对桶内元素进行基数排序        }    }}

LSD基数排序

基本思想

首先依据最低位排序码Kd对所有元素进行一趟排序,然后依据次低位排序码Kd1对上一趟排序的结果再排序,依次重复,直到依据排序码K1最后一趟排序完成,就可以得到一个有序的序列。使用这种排序方法对每个排序码进行排序时,不需要再分组,而是整个元素组都参加排序。

代码

private void lsdRadixSort(int[] a, int left, int right, int d) {    int[] auxArray = new int[a.length];// 辅助数组,存放按桶分配的结果,根据count[]预先算定各桶元素的使用位置    int[] count = new int[right-left+1];// 辅助数组,记录当处理第i位时各个元素的第i位取值为k的有多少个。    int i, j, k;    for (k = 1; k <= d; k++) {        for (i = 0; i < radix; i++)            count[i] = 0;        for (i = left; i <= right; i++)            count[getDigit(a[i], k)]++;        for (i = 1; i < radix; i++)            count[i] = count[i] + count[i - 1];        for (i = left; i <= right; i++) {            j = getDigit(a[i], k);            auxArray[count[j] - 1] = a[i];            count[j]--;        }        // 从辅助数组顺序写入原数组        for (i = left, j = 0; i <= right; i++, j++)            a[i] = auxArray[j];    }}
0 0
原创粉丝点击