算法學習記錄4 桶排序

本身的理解

這也能算個排序?感受這個就和slf4j同樣...定義了個接口.而後調用其餘排序來完成排序....java

而後還有個感受就是和HashMap同樣...不一樣的數值(key)分配到不一樣的桶(Map.entry)裏去...apache

而後每一個桶裏的一堆數值再調用其餘排序,好比快速排序去完成排序,最後把全部桶裏的數值按順序輸出就行了..數組

 

實現

 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 }

 

在以前的快速排序上稍微修改了下加了個方法ide

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
相關文章
相關標籤/搜索