目錄html
1.桶排序思想node
2.算法過程算法
3.算法實現代碼
數組
在開頭安利一個可視化網站:
框架
https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
ide
這上面有排序算法的可視化實現,可結合下文算法過程對照着圖學習。
函數
思想:
將待排序集合中處於同一值域的元素存入同一個桶中,
這樣的話,集合中的元素就被拆分紅多個桶,再對每一個桶中的元素排序,再將有序的桶放回原集合中。
一句話:經過「分配」和「收集」實現排序。
Notes:
(1).桶排序是對計數排序的改進。計數排序是給每個元素都開闢空間,記錄出現次數,以達到排序。
因此,對於數值過大的元素或者浮點數,計數排序就不能很很好的解決。
因此應用桶排序,能夠很好的解決,根據元素的分佈利用一個hash函數將值域相同的元素放到一個桶。
(2).桶排序的時間複雜度O(N)~O(N*logN),N爲元素個數。
(3).桶排序適用於元素均勻分佈的狀況。學習
算法過程:
(1).搭建桶的結構,使用單鏈表;
(2).hash函數定義:即如何肯定元素是否在同一值域中,網站
(value * len) / (max_value + 1);
value:當前計算的元素
len:待排序集合的長度
max_value:集合中數值最大的元素
(3).桶中元素排序:鏈表中元素的插入;
(4).出桶,排序輸出。this
3.代碼
public class buket_sort { public static void main(String[] args) { int[] arr={10,7,4,8,2,6,5,9,4}; System.out.println( "begin..." + Arrays.toString( arr ) ); new buket_sort().sort( arr ); System.out.println( "final..." + Arrays.toString( arr ) ); } /** * (value * len) / (max_value + 1) * 返回元素對應的桶的下標 * @param value * @param length * @param max * @return */ public static int hash(int value,int length,int max_value){ return (value * length) / (max_value + 1); } /** * 排序實現 * @param arr */ public static void sort(int []arr){ int len=arr.length; LinkedNode[] bucket=new LinkedNode[len];//桶的個數能夠是元素個數 int max=getMax(arr); // System.out.println(max); //入桶 for (int i = 0; i < len; i++) { int value=arr[i]; int index=hash(value, len, max); if(bucket[index] == null){ bucket[index]=new LinkedNode(value); }else{ insertInto(value,bucket[index],bucket,index); } } //出桶 int k=0; for(LinkedNode node :bucket){ if(node!=null){ while(node!=null){ arr[k++]=node.value; node=node.next; } } } } /** * 桶內元素排序 * 若是該元素小於頭節點,替換頭節點 * 若是大於,向後走,或插入到末尾或中間 * @param value 待排序元素值 * @param linkedNode 桶元素中頭節點 * @param bucket 用於替換頭節點 * @param index 下標 */ private static void insertInto(int value, LinkedNode head, LinkedNode[] bucket, int index) { LinkedNode newNode=new LinkedNode(value);//備份節點 if(value<=head.value){//替換頭節點 newNode.next=head; bucket[index]=newNode; return; } LinkedNode p=head; LinkedNode pre=p;//當前節點的前一個節點 while(p != null && value>p.value){ pre=p; p=p.next; } if(p==null){ pre.next=newNode; }else{ pre.next=newNode; newNode.next=p; } } /** * 獲得數組中最大的元素。 * * @param arr * @return */ private static int getMax(int[] arr) { int max=Integer.MIN_VALUE; int len=arr.length; for (int i = 0; i < len; i++) { if(arr[i]>max){ max=arr[i]; } } return max; } }
節點的框架
public class LinkedNode { public int value; public LinkedNode next; public LinkedNode(int value){ this.value=value; } }
實現結果: