从零单刷数据结构(Java描述)(十八)——排序之基数排序(桶排序)

基数排序(radix sort),又称桶排序(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。如先按个位排,再将元素按十位排,再将元素按百位排…直到达到最高位。基数排序法是属于稳定性的排序,其时间复杂度为O (nlog®m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

//桶排序
 public static void radixSort(int[]arr) {
        //存取数组中最大的数字
        int max=Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }
        }
        //计算最大数字是几位数
        int maxLength=(max+"").length();
        //用于临时存储数据的数组
        int[][]temp=new int[10][arr.length];
        //用于记录在temp中相应的数组中存放的数字数量
        int[]counts=new int[10];
        //根据最大长度的数决定比较的次数
        for (int i = 0,n=1; i < maxLength; i++,n*=10) {
            //把每一个数字分别计算余数
            for (int j = 0; j < arr.length; j++) {
                //计算余数
                int ys=arr[j]/n%10;
                //把当前遍历的数据放入指定的数组中
                temp[ys][counts[ys]]=arr[j];
                //记录数量
                counts[ys]++;
            }
            //记录取的元素需要放的位置
            int index=0;
            //把数字取出来
            for (int k = 0;k <counts.length; k++){
                    //记录数量的数组中当前余数记录的数量不为0
                    if(counts[k]!=0){
                        //循环取出元素
                        for (int l = 0; l <counts[k]; l++) {
                            //取出元素
                            arr[index]=temp[k][l];
                            //记录下一个位置
                            index++;
                        }
                        //把数量置为0
                        counts[k]=0;
                    }
                }                
            }
        }
import java.util.Arrays;
//测试类
class RadixSort{
    public static void main(String[] args) {
        int[]arr=new int[]{23,6,189,45,9,287,56,1,798,34,65,652,5};
        radixSort(arr);
        //输出[1, 5, 6, 9, 23, 34, 45, 56, 65, 189, 287, 652, 798]
        System.out.println(Arrays.toString(arr));
    }

由于桶排序原理上每次按位排序元素都遵循先进先出的规则,这里也可以使用队列实现桶排序。

//使用队列实现桶排序
 public static void radixQueueSort(int[]arr) {
        //存取数组中最大的数字
        int max=Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }
        }
        //计算最大数字是几位数
        int maxLength=(max+"").length();
        //用于临时存储数据的队列
        MyQueue[]temp=new MyQueue[10];
        //为队列数组赋值
        for (int i = 0; i < temp.length; i++) {
            temp[i]=new MyQueue();
        }
        //用于记录在temp中相应的数组中存放的数字数量
        int[]counts=new int[10];
        //根据最大长度的数决定比较的次数
        for (int i = 0,n=1; i < maxLength; i++,n*=10) {
            //把每一个数字分别计算余数
            for (int j = 0; j < arr.length; j++) {
                //计算余数
                int ys=arr[j]/n%10;
                //把当前遍历的数据放入指定的队列中
                temp[ys].enQueue(arr[j]);
            }
            //记录取的元素需要放的位置
            int index=0;
            //把所有队列中的数字取出来
            for (int k = 0;k <temp.length; k++){
                    //当前遍历的队列不为空,循环取出元素
                       while(!temp[k].isEmpty()){
                           //取出元素
                            arr[index]=temp[k].deQueue();
                            //记录下一个位置
                            index++;
                       }
                }                
            }
        }

猜你喜欢

转载自blog.csdn.net/waS_TransvolnoS/article/details/91553705
今日推荐