非比较排序:计数排序、桶排序、基数排序

一:什么是非比较排序
众所周知,排序有很多种办法,其中无非就是比较数组中的值,另一种就是一种分配的思想,类似于一个萝卜一个坑,这也就是非比较排序。

二:有哪些非比较排序呢?

可以分为三大类 计数排序 、 基数排序 、 桶排序 。这是比较常见的三种排序方式,当然核心思想都是 一个萝卜一个坑。

三:具体实现

1:计数排序
顾名思义,计数排序的核心思想就是统计待排序数组中,每个数出现的次数,使用另一个数组来记录致谢数据,等遍历一遍待排序数组之后,所有的数据的出现次数都记录了下来,再根据记录的数组进行还原。
这里记录数组的大小为待排序数组的最大值减去最小值,当某个元素出现一次,则在固定的下标出执行+1。
时间复杂度分析:遍历待排序数组 o(n) 第二遍遍历记录数组 o(range) 还原数组o(n) 故时间复杂度是o(n+range+n)

Java代码实现如下
  //计数排序
public static void CountingSorting(int[] array)
{
    int max=array[0];
    int min=array[0];
    //找到数组中的范围
    for (int i = 0; i < array.length; i++) {
        if (array[i]>max)
        {
            max=array[i];
        }
        if (array[i]<min)
        {
            min=array[i];
        }
    }
    //构建统计用的数组
    int[] tempory=new int[max-min+1];
    System.out.println(tempory.length+"--"+max+"---"+min);
    for (int i = 0; i < array.length; i++) {
        tempory[array[i]-min]++;
    }
    //写回到原数组
    int j=0;
    for (int i = 0; i < tempory.length; i++) {
        while (tempory[i]>0)
        {
            array[j++]=i+min;
            tempory[i]--;
        }
    }
    System.out.println(Arrays.toString(array));
}



2:基数排序
是 简单来说就是根据待排序序列的位来决定的,分别设置10个桶,然后分别对待排序的数进行取个位 十位,白位等等,放到对应的桶之中,每经历一遍,依次从桶之中拿出数据,再对新的待排序列进行操作,这时候就是取百分位了,每次都会上升一个数量级。

Java代码

//基数排序
public static void CardinalitySort(int[] array)
{
    //数组实现
    //先找到数组中的元素的最大值,确定最大的位数
    int max=array[0];
    for (int i = 0; i < array.length;i++) {
        if (array[i]>max)
        {
            max=array[i];
        }
    }
    //计算位数
    int time=0;
    while (max>0)
    {
        max/=10;
        time++;
    }
    //创建10个队列
    ArrayList<Integer>[] list=new ArrayList[10];
    for (int i = 0; i < 10; i++) {
            list[i]=new ArrayList<Integer>();
    }
    //开始循环
    for (int j = 0; j < time; j++)
    {
        for (int i = 0; i <array.length ; i++)
        {
            list[  array[i] %   (int)Math.pow(10, j+1)  /  (int)Math.pow(10, j) ]  .add(array[i]);
          if (j!=0)
          {
              Integer s=new Integer(array[i]);
              list[array[i] % (int) Math.pow(10, j) / (int) Math.pow(10, j - 1)].remove(s);
          }
        }
        int temp2=0;
            for (int i = 0; i < 10; i++)
            {
                for (int k = 0; k < list[i].size(); k++)
                {
                    array[temp2++]=list[i].get(k);
                }
            }
    }

    System.out.println(Arrays.toString(array));
}




2:桶排序

桶排序比较类似于上两个排序方式,不过桶类似于分治法,讲一个大的待排序数组分为多个桶内,再对多个桶中的序列进行排序。




实现代码:


//桶排序
//这里桶之中的数据,我们调用快速排序进行排序
public static void BucketSort(int[] array)
{
    //先找到范围
    int max=0,min=0;
    for (int i = 0; i <array.length; i++) {
        if (array[i]>max)
        {
            max=array[i];
        }
        if (array[i]<min)
        {
            min=array[i];
        }
    }
    int range=max-min;
    //分为几个桶这里取range/10 最小桶从min开始  到最大桶的max
    int bucketNum=range/10;
    int [][] bucket=new int[10][array.length];
    //记录桶之中的数据量
    int[] BucteDatetnum=new int[10];
    //这里放入桶之中
    for (int i = 0; i <array.length ; i++) {
        int index=(array[i]-min)/10;
        System.out.println("index"+"=="+index);
        bucket[index] [BucteDatetnum[index]] =array[i];
        BucteDatetnum[index]++;
    }
    //分别对每个桶进行快速排序
    for (int i = 0; i <10 ; i++) {
        QuickSort(bucket[i],0,BucteDatetnum[i]);
        System.out.println(Arrays.toString(bucket[i]));
    }
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值