【排序】桶排序 bucket sort

目錄html

 

1.桶排序思想node

2.算法過程算法

3.算法實現代碼
數組

 

在開頭安利一個可視化網站:
框架

https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
ide

這上面有排序算法的可視化實現,可結合下文算法過程對照着圖學習。

函數

    1. 思想:
      將待排序集合中處於同一值域的元素存入同一個桶中,
      這樣的話,集合中的元素就被拆分紅多個桶,再對每一個桶中的元素排序,再將有序的桶放回原集合中。
       一句話:經過「分配」和「收集」實現排序。
      Notes:
      (1).桶排序是對計數排序的改進。計數排序是給每個元素都開闢空間,記錄出現次數,以達到排序。
      因此,對於數值過大的元素或者浮點數,計數排序就不能很很好的解決。
      因此應用桶排序,能夠很好的解決,根據元素的分佈利用一個hash函數將值域相同的元素放到一個桶。
      (2).桶排序的時間複雜度O(N)~O(N*logN),N爲元素個數。
      (3).桶排序適用於元素均勻分佈的狀況。
      學習

    2. 算法過程:
      (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;
  }
}
bucket sort

節點的框架

 

public class LinkedNode {
  public int value;
  public LinkedNode next;

  public LinkedNode(int value){
    this.value=value;
  }
}
LinkedNode

 

       實現結果:

  

相關文章
相關標籤/搜索