• 算法学习记录4 桶排序


    自己的理解

    这也能算个排序?感觉这个就和slf4j一样...定义了个接口.然后调用其他排序来完成排序....

    然后还有个感觉就是和HashMap一样...不同的数值(key)分配到不同的桶(Map.entry)里去...

    然后每个桶里的一堆数值再调用其他排序,比如快速排序去完成排序,最后把所有桶里的数值按顺序输出就好了..

    实现

     1 package algorithm;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Arrays;
     5 
     6 import org.apache.commons.lang3.ArrayUtils;
     7 
     8 /**
     9  * 桶排序
    10  * 
    11  * @author jyzjyz12@163.com
    12  * @since 2017年3月6日 下午1:37:56
    13  */
    14 public class BucketSortTest1 {
    15 
    16     public static void main(String[] args) {
    17         int[] arr1 = { 4, 7, 5, 6, 1, 3, 8 };
    18         int[] arr2 = { 7, 6, 5, 4, 3, 2, 1 };
    19         int[] arr3 = { 5, 9, 3, 7, 8, 6, 1, 2, 4 };
    20         int[] arr4 = { 13, 2, 5, 4, 88, 76, 68, 87, 55, 88, 88, 77, 67, 99, 100, 5, 53, 52, 51, 66 };
    21         System.out.println(Arrays.toString(sort(arr1)));
    22         System.out.println(Arrays.toString(sort(arr2)));
    23         System.out.println(Arrays.toString(sort(arr3)));
    24         System.out.println(Arrays.toString(sort(arr4)));
    25     }
    26 
    27     public static int[] sort(int[] arr) {
    28         int[] result = new int[arr.length];
    29         Node[] buckets = new Node[11];// 11个桶,数组里的数字是0-100之间的,到底选取几个桶,取决于具体排序的数字范围
    30         for (int i = 0; i < arr.length; i++) {
    31             int index = arr[i] / 11;
    32             if (buckets[index] == null) {
    33                 buckets[index] = new Node(arr[i]);
    34             } else {
    35                 Node newNode = new Node(arr[i]);
    36                 newNode.next = buckets[index];
    37                 buckets[index] = newNode;
    38             }
    39 
    40         }
    41 
    42         int position = 0;// 将各个bucket里的数据复制到result中,所以记录下当前bucket要从result中的哪个位置开始复制
    43         for (Node bucket : buckets) {
    44             if (bucket == null) { // 空的桶
    45                 continue;
    46             }
    47             Integer[] one = Node.getAllValue(bucket);// 这个桶中的所有数值
    48             System.arraycopy(QuickSortTest1.getSortedArr(ArrayUtils.toPrimitive(one)), 0, result, position, one.length);// 把每个bucket中的数值复制到result中,每个bucket里的数值用之前写的快速排序去排序
    49             position += one.length;
    50         }
    51         return result;
    52     }
    53 
    54     private static class Node {
    55         public static Integer[] getAllValue(Node n) {
    56             ArrayList<Integer> result = new ArrayList<Integer>();// 这里导致了int[]和integer[]之间的转化,但是也没啥办法,因为不知道这个bucket里有多少个数值,或者之前不要用Node[]了,直接用ArrayList<ArrayList<Integer>>
    57             while (n != null) {
    58                 result.add(n.value);
    59                 n = n.next;
    60             }
    61             return result.toArray(new Integer[0]);
    62         }
    63 
    64         public int value;
    65         public Node next;
    66 
    67         public Node(int value) {
    68             this.value = value;
    69         }
    70     }
    71 }

    在之前的快速排序上稍微修改了下加了个方法

    package algorithm;
    
    import java.util.Arrays;
    
    /**
     * 快速排序
     * 
     * @author jyzjyz12@163.com
     * @since 2017年2月27日 上午10:26:08
     */
    public class QuickSortTest1 {
        public static void main(String[] args) {
            int[] arr1 = { 4, 7, 5, 6, 1, 3, 8 };
            int[] arr2 = { 7, 6, 5, 4, 3, 2, 1 };
            int[] arr3 = { 5, 9, 3, 7, 8, 6, 1, 2, 4 };
            int[] arr4 = { 13, 2, 5, 4, 88, 76, 68, 87, 55, 88, 88, 77, 67, 99, 100, 5, 53, 52, 51, 66 };
            sort(arr1);
            sort(arr2);
            sort(arr3);
            sort(arr4);
            System.out.println(Arrays.toString(arr1));
            System.out.println(Arrays.toString(arr2));
            System.out.println(Arrays.toString(arr3));
            System.out.println(Arrays.toString(arr4));
        }
    
        public static int[] getSortedArr(int[] arr) {
            int[] result = Arrays.copyOf(arr, arr.length);
            sort(result);
            return result;
        }
    
        public static void sort(int[] arr) {
            sortInternal(arr, 0, arr.length - 1);
        }
    
        private static void sortInternal(int[] arr, int low, int high) {
            // 当然只有1个元素的时候就不需要排序了,这里low>=而不是=是因为下面
            // sortInternal(arr, currPosition + 1, high);
            // currPositon+1可能会导致low=hight的时候low+1>high
            if (low >= high) { // 这个if是递归结束条件
                return;
            } else { // 递归分解条件
                int currPosition = sortOnce(arr, low, high); // 得到一个基准值的最终位置,左边的数字都比它小,右边都比它大
                sortInternal(arr, low, currPosition - 1); // 左边的数字继续递归进行快速排序
                sortInternal(arr, currPosition + 1, high);// 右边的数字继续递归进行快速排序
            }
        }
    
        /**
         * 一轮排序
         * 
         * @param arr
         *            待排序数组
         * @param low
         *            头指针
         * @param high
         *            尾指针
         * @return 基准的位置
         */
        private static int sortOnce(int[] arr, int low, int high) {
            int key = arr[low]; // 基准有很多种选择方法,取最左边的元素只是一种方法
            while (high > low) {// 每一轮终止条件是2个指针重合
                while (high > low) { // 每一轮开始先移动尾指针
                    if (arr[high] > key) { // high的数字比基准大
                        high--; // high向前移动
                    } else {
                        swap(arr, low, high); // 交换low和high位置的数字
                        low++;// 交换过位置了不用再次判断,所以low++
                        break;// 准备开始头指针的移动
                    }
                }
                while (high > low) {// 头指针和尾指针交换过位置的话再开始移动头指针,再交换的话继续下个外层while循环继续移动头指针
                    if (arr[low] < key) { // low的数字比基准小
                        low++;// low向后移动
                    } else {
                        swap(arr, low, high);// 交换low和high位置的数字
                        high--;// 交换过位置了不用再次判断,所以high--
                        break;// 准备开始尾指针的移动
                    }
                }
            }
            return low;// high和low重合,返回哪个都一样
        }
    
        /**
         * 交换数字high和low位置的2个数字
         * 
         * @param arr
         * @param p1
         * @param p2
         */
        private static void swap(int[] arr, int p1, int p2) {
            int temp = arr[p1];
            arr[p1] = arr[p2];
            arr[p2] = temp;
        }
    }
    View Code
  • 相关阅读:
    【Spring Framework】10、代理模式
    【Spring Framework】8、使用注解开发
    Codeforces 516E
    AtCoder Grand Contest 055 题解
    Codeforces 1606F
    贪心/构造/DP 杂题选做
    整数拆分最大乘积
    CSP-S2021 被碾压记
    洛谷 P2791
    LCT 小记
  • 原文地址:https://www.cnblogs.com/abcwt112/p/6510091.html
Copyright © 2020-2023  润新知