Java算法排序【这里最详细】

最详细的算法排序

一 :捅排序
话不多说,先上demo

public class BucketSort {

    private int[] buckets;

    private int[] array = {5,9,1,9,5,3,7,6,1};

    private String TAG = "zlq";

    public BucketSort() {
        this.buckets = new int [array.length + 1];
    }
    
     public void sort(){
        if(array != null && array.length > 1) {
            for(int i = 0; i < array.length; i++) {
                //把每个出现的值放到buckets数组里面 进行 +1 操作。
                //比如第一个值是 5,那么 buckets[5] ++; buckets[5] == 1;
                int value = array[i];
                buckets[value]++;
            }
        }

    }
    
    public void print() {
        //for 表达式 一般都有三个值 来计算。遇到复杂点的表达式不要怕。
        // 一般就有 int i = **; i <( 或者> ) **; i ++; (i-- ,++i,--i); 也就是三个 true; 一个等于false 不成立。
        //这种明显是 由大到小排序。
        for (int i = buckets.length - 1; i >= 0; i--) {
            //根据循环buckets[i]中的数值大小(出现的次数)。去打印出现的数值。也就是捅排序
            for (int j = 0; j < buckets[i]; j++) {
                Log.i(TAG,"print: 捅排序结果 i== " + i + " 在捅中出现的次数 buckets[i] ==  " + buckets[i]);
            }
        }
    }
} 

打印结果:

zlq: print: 捅排序结果 i== 9 在捅中出现的次数 buckets[i] ==  2
zlq: print: 捅排序结果 i== 9 在捅中出现的次数 buckets[i] ==  2
zlq: print: 捅排序结果 i== 7 在捅中出现的次数 buckets[i] ==  1
zlq: print: 捅排序结果 i== 6 在捅中出现的次数 buckets[i] ==  1
zlq: print: 捅排序结果 i== 5 在捅中出现的次数 buckets[i] ==  2
zlq: print: 捅排序结果 i== 5 在捅中出现的次数 buckets[i] ==  2
zlq: print: 捅排序结果 i== 3 在捅中出现的次数 buckets[i] ==  1
zlq: print: 捅排序结果 i== 1 在捅中出现的次数 buckets[i] ==  2
zlq: print: 捅排序结果 i== 1 在捅中出现的次数 buckets[i] ==  2

最详细的讲解来了 1: 讲解 sort() 方法 。

 /**
     *捅排序法 : sort() 方法:
     *
     * 1 .需要两个数组,一个数组是一串不规律的数字数组.另一个数组是为它排序的数组
     * 
     * 2 .将不规律的数组进行循环,将其中的数字比如 int[] array = {5,9,1,9,5,3,7,6,1};
     *    array[2] 是 数字 9,然后使用另外一个数组 int[] buckets = new int[array.length + 1]; ***为什么要 array .length + 1呢 ,稍后说.
     *    buckets[array[2]]++; 在循环里,相当于是数字 buckets[9] ++; 所以在buckets数组中
     *    把每一个数字出现的次数都进行了 +1操作。因为array[2] 的值是 数字 9 ,所以 buckets数组中buckets[9]的位置
     *    会 + 1。也就是 buckets[9] 的值 == 1.所以在array数组中 数字 9一共出现两次也就是
     *    buckets[9] 的值应该是 2.
     */

2 : print() 方法

/**
     * 捅排序法 : print() 进行排序
     * 1 .先去循环buckets数组的长度,buckets数组长度应该是 10。
     * 
     * 2 .由于这里是从大到小排序,那么取出的第一个buckets[10]的话会数组下标越界,
     *    因为虽然有十位数,但是计算机中是从0开始计算的,所以buckets[10]会出现数组下标越界异常。
     *    此时应该 buckets.length -1。但是 刚才为什么要**int[] buckets = new int[array.length + 1]**呢,
     *    聪明人一眼就明白了,因为我们array中的最大数字是 9 。也就意味着buckets[9] 至少会出现一次。
     *    如果我们得buckets长度只有 array.length 的话。也就是长度只有9,那么buckets[9]。也会报数组下标越界。
     *
     * 3 .再去循环buckets[9],发现buckets[9] = 2. 逆向思维一下,buckets[9] = 2.说明在buckets中
     *    我们之前存的数字 9 有两次,所以将数字 9 (也就是 i )取出就好.
     *    buckets[9]的话是出现了 2 次。所以数字排序应该是 9,9....然后依次类推buckets[8],buckets[7]...
     *    buckets[8]出现的次数是 0,比如buckets[8] == 0 ,肯定无法循环,循环条件不成立。也就是不走打印的方法。
     *    buckets[7]出现的次数是 1,取出来打印(也就是 i )。现在也是就9,9,7...
     *    buckets[6]出现的次数是 1,取出来打印(也就是 i )。现在也是就9,9,7,6...
     *    buckets[5]出现的次数是 2,取出来打印(也就是 i )。现在也是就9,9,7,6,5,5...
     *    buckets[4]出现的次数是 0,无法循环,循环条件不成立。
     *    buckets[3]出现的次数是 1,取出来打印(也就是 i )。现在也是就9,9,7,6,5,5,3...
     *    buckets[2]...
     *    buckets[1]...
     *    buckets[0]...
     */

捅排序缺点 :
1.浪费资源,如果有 10000这样的值在的话,捅的大小应该是 10000 + 1。

2.,对于精度类型无法进行精度排序,只能强转为int 排序。

3.不能对字符串进行排序。比如姓名 得分情况这样的场景。

二 :冒泡排序

很多入门选手对这个东西都死记硬背,工作用得少,面试只要求会写什么的。其实在冒泡中有很多写法…我这只介绍一种比较通用的~

老规矩 先上demo !!!

public class BubbleSort {
    private int [] array = null;
    private String TAG = "zlq";

    public BubbleSort(){
        //array = new int[]{10,8,20,26,25,18,20,20,12,9,11,14,0,3,5,7,0,0,0};
        array = new int[]{6,8,7,9,5,10,3,4,0,1,2};
    }
    public void smallToBigBubbleSort(){
        if (array != null && array.length > 0){

            for (int i = 1; i < array.length; i++) {

                for (int j = 1; j <= array.length - i; j++) {

                    if (array[j - 1] > array[j]) {

                        int temp = array[j];

                        array[j] = array[j - 1];

                        array[j - 1] = temp;
                    }
                }
            }
            for (int i : array) {
                Log.i(TAG, "bubbleSort:从小到大 array " + i);
            }
        }
    }


   public void bigToSmallBubbleSort(){

       if (array != null && array.length > 0){

           for (int i = 1; i < array.length; i++) {

               for (int j = 0; j < array.length - i; j++) {

                   if (array[j] < array[j + 1]){

                       int temp = array[j + 1];

                       array[j + 1] = array[j];

                       array[j] = temp;
                   }
               }
           }
           for (int i : array) {
               Log.i(TAG, "bubbleSort: 从大到小 array " + i);
           }
       }
   }
} 

打印结果:

zlq: bubbleSort:从小到大 array 0  
zlq: bubbleSort:从小到大 array 1
zlq: bubbleSort:从小到大 array 2
zlq: bubbleSort:从小到大 array 3
zlq: bubbleSort:从小到大 array 4
zlq: bubbleSort:从小到大 array 5
zlq: bubbleSort:从小到大 array 6
zlq: bubbleSort:从小到大 array 7
zlq: bubbleSort:从小到大 array 8
zlq: bubbleSort:从小到大 array 9
zlq: bubbleSort:从小到大 array 10

smallToBigBubbleSort 方法讲解 :

 /**
     * 冒泡排序心得总结:
     * 先上数组: int[] array = new int[]{6,8,7,9,5,10,3,4,0,1,2}; 数组 0 - 10; 11位数。
     *
     * 1.在for表达式中可以任意写,但是要注意第二个循环里面要比第一个循环少一位数。但是这两层循环的次数一定要相等。
     *   比如 : 第一层for中 int i = 1; i < array.length; i++; i 的值等于 1,然后小于 11(array.length)
     *   第二层循环中就要写成 int j = 1; j <= array.length - i; j++; 每循环一遍次让array的数组 -i。
     *   此时 在第一层循环中 i++;也就意味着 i 的值在增长,i 的初始值是 1。也就是 j 的值等于 1;然后小于等于 10(array.length)
     *   刚好少一位数,所以当第二层循环 j ++ 的时候 j 的值会不断变大。在数组中的位置也会慢慢移动。
     *   j 每加一次。array[j -1] < array[j] 就会形成 array[2] 跟 array[3]比较。也会 array[4] 和 array[5] 比较。
     *
     *   2.在这还要注意一点。不管是array[j - 1],还是array[j + 1],都不要超过 array.length这个值。不然会数组下标越界。
     *
     *   3.下面这个循环只需要改变一个 大于号 就可以改变是从小到大排序 还是从大到小排序
     *
     *   4. array[j + 1] 或者 array[j -1 ]。这两个的值用 temp 记录下来。然后赋值给 array[j],交换位置,就能决定是由大到小排序
     *      反之 array[j] 用 temp 记录下来然后再交换位置 就是从小到大排序。
     */

bigToSmallBubbleSort 这个方法的原理同上。

以上是自己发现的一些总结, 希望能帮助到需要帮助的人。最重要的是记录下来能帮助自己!!! 如有不足之处,欢迎各位指出宝贵的意见~

接下来不出意外的话,将会慢慢更新自己总结到的一些简单算法知识~

记录代码的漫长之路~
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值