非比較排序:計數排序、桶排序、基數排序
阿新 • • 發佈:2019-02-02
一:什麼是非比較排序 眾所周知,排序有很多種辦法,其中無非就是比較陣列中的值,另一種就是一種分配的思想,類似於一個蘿蔔一個坑,這也就是非比較排序。二:有哪些非比較排序呢? 可以分為三大類 計數排序 、 基數排序 、 桶排序 。這是比較常見的三種排序方式,當然核心思想都是 一個蘿蔔一個坑。三:具體實現 1:計數排序 顧名思義,計數排序的核心思想就是統計待排序陣列中,每個數出現的次數,使用另一個數組來記錄致謝資料,等遍歷一遍待排序陣列之後,所有的資料的出現次數都記錄了下來,再根據記錄的陣列進行還原。 這裡記錄陣列的大小為待排序陣列的最大值減去最小值,當某個元素出現一次,則在固定的下標出執行+1。 時間複雜度分析:遍歷待排序陣列 o(n) 第二遍遍歷記錄陣列 o(range) 還原陣列o(n) 故時間複雜度是o(n+range+n) Java程式碼實現如下
2:基數排序是 簡單來說就是根據待排序序列的位來決定的,分別設定10個桶,然後分別對待排序的數進行取個位 十位,白位等等,放到對應的桶之中,每經歷一遍,依次從桶之中拿出資料,再對新的待排序列進行操作,這時候就是取百分位了,每次都會上升一個數量級。 Java程式碼
2:桶排序桶排序比較類似於上兩個排序方式,不過桶類似於分治法,講一個大的待排序陣列分為多個桶內,再對多個桶中的序列進行排序。 實現程式碼:
//計數排序 public static void CountingSorting(int[] array) { int max=array[0]; int min=array[0]; //找到陣列中的範圍 for (int i = 0; i < array.length; i++) { if (array[i]>max) { max=array[i]; } if (array[i]<min) { min=array[i]; } } //構建統計用的陣列 int[] tempory=new int[max-min+1]; System.out.println(tempory.length+"--"+max+"---"+min); for (int i = 0; i < array.length; i++) { tempory[array[i]-min]++; } //寫回到原陣列 int j=0; for (int i = 0; i < tempory.length; i++) { while (tempory[i]>0) { array[j++]=i+min; tempory[i]--; } } System.out.println(Arrays.toString(array)); }
2:基數排序是 簡單來說就是根據待排序序列的位來決定的,分別設定10個桶,然後分別對待排序的數進行取個位 十位,白位等等,放到對應的桶之中,每經歷一遍,依次從桶之中拿出資料,再對新的待排序列進行操作,這時候就是取百分位了,每次都會上升一個數量級。 Java程式碼
//基數排序 public static void CardinalitySort(int[] array) { //陣列實現 //先找到陣列中的元素的最大值,確定最大的位數 int max=array[0]; for (int i = 0; i < array.length;i++) { if (array[i]>max) { max=array[i]; } } //計算位數 int time=0; while (max>0) { max/=10; time++; } //建立10個佇列 ArrayList<Integer>[] list=new ArrayList[10]; for (int i = 0; i < 10; i++) { list[i]=new ArrayList<Integer>(); } //開始迴圈 for (int j = 0; j < time; j++) { for (int i = 0; i <array.length ; i++) { list[ array[i] % (int)Math.pow(10, j+1) / (int)Math.pow(10, j) ] .add(array[i]); if (j!=0) { Integer s=new Integer(array[i]); list[array[i] % (int) Math.pow(10, j) / (int) Math.pow(10, j - 1)].remove(s); } } int temp2=0; for (int i = 0; i < 10; i++) { for (int k = 0; k < list[i].size(); k++) { array[temp2++]=list[i].get(k); } } } System.out.println(Arrays.toString(array)); }
2:桶排序桶排序比較類似於上兩個排序方式,不過桶類似於分治法,講一個大的待排序陣列分為多個桶內,再對多個桶中的序列進行排序。 實現程式碼:
//桶排序 //這裡桶之中的資料,我們呼叫快速排序進行排序 public static void BucketSort(int[] array) { //先找到範圍 int max=0,min=0; for (int i = 0; i <array.length; i++) { if (array[i]>max) { max=array[i]; } if (array[i]<min) { min=array[i]; } } int range=max-min; //分為幾個桶這裡取range/10 最小桶從min開始 到最大桶的max int bucketNum=range/10; int [][] bucket=new int[10][array.length]; //記錄桶之中的資料量 int[] BucteDatetnum=new int[10]; //這裡放入桶之中 for (int i = 0; i <array.length ; i++) { int index=(array[i]-min)/10; System.out.println("index"+"=="+index); bucket[index] [BucteDatetnum[index]] =array[i]; BucteDatetnum[index]++; } //分別對每個桶進行快速排序 for (int i = 0; i <10 ; i++) { QuickSort(bucket[i],0,BucteDatetnum[i]); System.out.println(Arrays.toString(bucket[i])); } }