日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言:

本文章主要是講解我個人在學習JAVA開發環境的排序算法時做的一些準備,以及個人的心得體會,匯集成本篇文章,作為自己對排序算法理解的總結與筆記。

內容主要是關于十大經典排序算法的簡介、原理、動靜態圖解和源碼實現的分析。

對于一名程序員來講,我們都知道數據結構與算法起初是用于C語言居多,然而在Java語言下使用算法的案例卻很少,因此,特別整理了在Java開發環境的排序算法,供大家一起學習探討。

一、排序算法

1.排序算法概述(百度百科):

所謂排序算法,即通過特定的算法因式將一組或多組數據按照既定模式進行重新排序。這種新序列遵循著一定的規則,體現出一定的規律,因此,經處理后的數據便于篩選和計算,大大提高了計算效率。對于排序,我們首先要求其具有一定的穩定性,即當兩個相同的元素同時出現于某個序列之中,則經過一定的排序算法之后,兩者在排序前后的相對位置不發生變化。換言之,即便是兩個完全相同的元素,它們在排序過程中也是各有區別的,不允許混淆不清。

2.《數據結構與算法》中的排序算法

常見的排序算法有:插入排序、希爾排序、選擇排序、冒泡排序、歸并排序、快速排序、堆排序、基數排序等。

算法圖解(菜鳥教程借圖):

十大經典排序算法(java實現、配圖解,附源碼)

 

圖解分析:

十大經典排序算法(java實現、配圖解,附源碼)

 

3.算法分析

時間復雜度

平方階 (O(n2)) 排序 各類簡單排序:直接插入、直接選擇和冒泡排序。

線性對數階 (O(nlog2n)) 排序 快速排序、堆排序和歸并排序;

O(n1+§)) 排序,§ 是介于 0 和 1 之間的常數。 希爾排序

線性階 (O(n)) 排序 基數排序,此外還有桶、箱排序。

關于穩定性

穩定的排序算法:冒泡排序、插入排序、歸并排序和基數排序。

不是穩定的排序算法:選擇排序、快速排序、希爾排序、堆排序。

名詞解釋:

  • n:數據規模
  • k:"桶"的個數
  • In-place:占用常數內存,不占用額外內存
  • Out-place:占用額外內存
  • 穩定性:排序后 2 個相等鍵值的順序和排序之前它們的順序相同
  1. 平均時間復雜度是指所有可能的輸入實例均以等概率的出現情況下得到算法的運行時間
  2. 最壞時間復雜度,一般討論的時間復雜度均是最壞情況下的時間復雜度,這樣做的原因是最壞情況下的時間復雜度是算法在任何輸入實例上運行的界限,這就保證了算法的運行時間不會比最壞情況更長。
  3. 平均時間復雜度和最壞時間復雜度是否一樣,這就需要根據算法不同而不同了。

二、十大經典排序算法(Java開發版)

PS:案例均以數組{15,63,97,12,235,66}排序為例

1.冒泡排序

冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法。

它重復地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果順序(如從大到小、首字母從Z到A)錯誤就把他們交換過來。走訪元素的工作是重復地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成。

這個算法的名字由來是因為越小的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“冒泡排序”。

1.1實現原理

  • 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
  • 對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
  • 針對所有的元素重復以上的步驟,除了最后一個。
  • 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
十大經典排序算法(java實現、配圖解,附源碼)

 

1.2動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

1.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 import java.util.Arrays;
 2 public class BubbleSort {
 3     public static void main(String[] args) {
 4         int[] arrays =new int[]{15,63,97,12,235,66};
 5         for (int i=0;i<arrays.length-1;i++){
 6             
 7 //            控制比較次數,三者交換,實現排序
 8             for(int j=0;j<arrays.length-1-i;j++){
 9                 if (arrays[j] > arrays[j+1]){
10                     int temp = 0;//類似空桶
11                     temp = arrays[j]; //A桶中水倒入空桶C中
12                     arrays[j] = arrays[j+1];//把B桶的水倒入A桶中
13                     arrays[j+1] = temp;//把C桶的水倒入B桶中
14                 }
15             }
16         }
17         System.out.println(Arrays.toString(arrays));
18     }
19 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

2.快速排序

快速排序(Quicksort),計算機科學詞匯,適用領域Pascal,c++等語言,是對冒泡排序算法的一種改進。

2.1實現原理

快速排序是對冒泡排序的一種改進。通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另一部分所有的數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列

十大經典排序算法(java實現、配圖解,附源碼)

 

2.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

2.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 import java.util.Arrays;
 2 public class QuickSort {
 3     public static void main(String[] args) {
 4         int[] arrays = new int[]{15,63,97,12,235,66};
 5         sort(arrays,0,arrays.length-1);
 6         System.out.println(Arrays.toString(arrays));
 7     }
 8     public static void sort(int[] arrays,int left,int right){
 9         int l  = left;
10         int r = right;
11 
12         int pivot = arrays[(left+right)/2];
13         int temp = 0;
14         while (l<r){
15 
16             //在左邊查找小于中間值的
17             while(arrays[l]<pivot){
18                 l++;
19             }
20             //查詢右邊小于中間值
21             while (arrays[r]>pivot){
22                 r--;
23             }
24             if (l>=r){
25                 break;
26             }
27             temp = arrays[l];
28             arrays[l] = arrays[r];
29             arrays[r] = temp;
30 
31 //            交換完數據arrays[l] = pivot
32             if (arrays[l]==pivot){
33                 r--;
34             }
35             if (arrays[r]==pivot){
36                 l++;
37             }
38             if (r==l){
39                 l++;
40                 r--;
41             }
42             if (left<r){
43                 sort(arrays,left,r);
44             }
45             if (right>l){
46                 sort(arrays,l,right);
47             }
48         }
49     }
50 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

3.基數排序

基數排序(radix sort)屬于“分配式排序”(distribution sort),又稱“桶子法”(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達到排序的作用,基數排序法是屬于穩定性的排序,其時間復雜度為O (nlog(r)m),其中r為所采取的基數,而m為堆數,在某些時候,基數排序法的效率高于其它的穩定性排序法。

基數排序是1887年赫爾曼、何樂禮發明的。思想是講整數按位數切割成不同的數字,然后按每個位數分別比較。

3.1實現原理

講所有的待比較數值統一設置為同樣的數位長度,位數比較短的數前面補零,然后從最地位開始依次進行一次排序,這樣從最低位排序一直到最高位排序完成以后,數列就變成一個有序序列。

十大經典排序算法(java實現、配圖解,附源碼)

 

3.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

3.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

  1 import java.text.SimpleDateFormat;
  2 import java.util.Arrays;
  3 import java.util.Date;
  4 
  5 public class BasicSort {
  6 
  7     public static void main(String[] args) {
  8         int[] arrays = new int[]{15,63,97,12,235,66};
  9         SimpleDateFormat simpleDateFormat  =new SimpleDateFormat("yyyy-mm-dd HH:MM:ss:SS");
 10         System.out.println("開始排序前:"+simpleDateFormat.format(new Date()));
 11         sort(arrays);
 12         System.out.println("排序結束:"+simpleDateFormat.format(new Date()));
 13     }
 14 
 15 //     1.獲取原序列的最大位多少
 16 //      @param arrays
 17     public static void sort(int[] arrays){
 18 
 19 //        獲取最大位數
 20         int max = 0;
 21         for(int i=0;i<arrays.length;i++){
 22             if (arrays[i]>max){
 23                 max = arrays[i];
 24             }
 25         }
 26 
 27 //        獲取字符串長度,所以把int類型轉字符串類型
 28         int maxLength = (max+"").length();
 29 
 30 //      定義二維數組,大小10,表示10個桶,每一個桶則是一個數組
 31 //       [[],[],[],[],[]...]
 32         int[][] bucket = new int[10][arrays.length];
 33 
 34 //        輔助數組
 35         int[] bucketElementCount = new int[10];
 36 
 37 //        循環獲取無序數列
 38         for (int j=0;j<arrays.length;j++){
 39             int locationElement = arrays[j]%10;
 40 
 41 //            放入桶中
 42             bucket[locationElement][bucketElementCount[locationElement]] = arrays[j] ;
 43             bucketElementCount[locationElement]++;
 44         }
 45 
 46 //        遍歷每一個桶,講元素存放原數組中
 47         int index = 0;
 48         for (int k = 0;k<bucketElementCount.length;k++){
 49             if (bucketElementCount[k] !=0){
 50                 for (int l = 0;l<bucketElementCount[k];l++){
 51                     arrays[index++] = bucket[k][l];
 52                 }
 53             }
 54             bucketElementCount[k] = 0;
 55         }
 56         System.out.println(Arrays.toString(arrays));
 57 
 58 //        第一輪針對個位數進行比較
 59         for (int j = 0;j<arrays.length;j++){
 60             int locationElement = arrays[j]/1%10;
 61 
 62             bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];
 63             bucketElementCount[locationElement]++;
 64         }
 65 
 66 //        取出來按照桶的順序放回原數組中
 67         int indx = 0;
 68         for (int k = 0;k<bucketElementCount.length;k++){
 69             if (bucketElementCount[k] !=0){
 70                 for (int l=0;l<bucketElementCount[k];l++){
 71                     arrays[indx++] = bucket[k][l];
 72                 }
 73             }
 74             bucketElementCount[k] = 0;
 75         }
 76 
 77 //        判斷十位數
 78         for (int j = 0;j<arrays.length;j++){
 79             int locationElement = arrays[j]/10%10;
 80 
 81             bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];
 82             bucketElementCount[locationElement]++;
 83         }
 84 
 85 //        取出來按照桶的順序放回原數組中
 86         indx = 0;
 87         for (int k = 0;k<bucketElementCount.length;k++){
 88             if (bucketElementCount[k] !=0){
 89                 for (int l=0;l<bucketElementCount[k];l++){
 90                     arrays[indx++] = bucket[k][l];
 91                 }
 92             }
 93             bucketElementCount[k] = 0;
 94         }
 95 
 96 //        獲取百位數比較
 97         for (int j = 0;j<arrays.length;j++){
 98             int locationElement = arrays[j]/100%10;
 99 
100             bucket[locationElement][bucketElementCount[locationElement]] = arrays[j];
101             bucketElementCount[locationElement]++;
102         }
103 
104 //        取出來按照桶的順序放回原數組中
105         indx = 0;
106         for (int k = 0;k<bucketElementCount.length;k++){
107             if (bucketElementCount[k] !=0){
108                 for (int l=0;l<bucketElementCount[k];l++){
109                     arrays[indx++] = bucket[k][l];
110                 }
111             }
112             bucketElementCount[k] = 0;
113         }
114         System.out.println("基數排序后的順序:"+Arrays.toString(arrays));
115     }
116 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

4.插入排序

插入排序,一般也被稱為直接插入排序。對于少量元素的排序,它是一個有效的算法 。插入排序是一種最簡單的排序方法,它的基本思想是將一個記錄插入到已經排好序的有序表中,從而一個新的、記錄數增1的有序表。在其實現過程使用雙層循環,外層循環對除了第一個元素之外的所有元素,內層循環對當前元素前面有序表進行待插入位置查找,并進行移動 。

4.1實現原理

插入排序的工作方式像許多人排序一手撲克牌。開始時,我們的左手為空并且桌子上的牌面向下。然后,我們每次從桌子上拿走一張牌并將它插入左手中正確的位置。為了找到一張牌的正確位置,我們從右到左將它與已在手中的每張牌進行比較。拿在左手上的牌總是排序好的,原來這些牌是桌子上牌堆中頂部的牌。

插入排序是指在待排序的元素中,假設前面n-1(其中n>=2)個數已經是排好順序的,現將第n個數插到前面已經排好的序列中,然后找到合適自己的位置,使得插入第n個數的這個序列也是排好順序的。按照此法對所有元素進行插入,直到整個序列排為有序的過程,稱為插入排序。

十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

4.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 public class InsertSort {
 2     public static void main(String[] args) {
 3         int[] array = new int[]{15,63,97,12,235,66};
 4         //控制拿去每一個元素
 5         for(int i=1;i<array.length;i++){
 6             //比較次數
 7             for (int j=i;j>=1;j--){
 8                 //是否小于前面的元素
 9                 if (array[j]<array[j-1]){
10                     int temp = 0;
11                     temp = array[j];
12                     array[j] = array[j-1];
13                     array[j-1] = temp;
14                 }else {
15                     //continue 與 break
16                     break;
17                 }
18             }
19         }
20         System.out.println("排序后的結果:"+ Arrays.toString(array));
21     }
22 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

5.選擇排序

選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是:第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,然后放到已排序的序列的末尾。以此類推,直到全部待排序的數據元素的個數為零。選擇排序是不穩定的排序方法。

5.1實現原理

第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,然后放到已排序的序列的末尾。以此類推,直到全部待排序的數據元素的個數為零。選擇排序是不穩定的排序方法。

十大經典排序算法(java實現、配圖解,附源碼)

 

5.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

5.3實例展示

 1 import java.util.Arrays;
 2 public class SelectSort {
 3     public static void main(String[] args) {
 4         int[] arr = new int[]{15,63,97,12,235,66};
 5         for (int i=0;i<arr.length;i++){
 6 
 7             for (int j=arr.length-1;j>i;j--){
 8 
 9                 if (arr[j]<arr[i]){
10 
11                     int temp = 0;
12                     temp = arr[j];
13                     arr[j] = arr[i];
14                     arr[i] = temp;
15                 }
16             }
17         }
18         System.out.println("選擇排序后的結果:"+ Arrays.toString(arr));
19     }
20 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

6.希爾排序

希爾排序(Shell's Sort)是插入排序的一種又稱“縮小增量排序”(Diminishing Increment Sort),是插入排序算法的一種更高效的改進版本。希爾排序是非穩定排序算法。該方法因 D.L.Shell 于 1959 年提出而得名。

希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至 1 時,整個文件恰被分成一組,算法便終止。

6.1實現原理

先取一個小于n的整數d1作為第一個增量,把文件的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然后,取第二個增量d2

般的初次取序列的一半為增量,以后每次減半,直到增量為1。

十大經典排序算法(java實現、配圖解,附源碼)

 


十大經典排序算法(java實現、配圖解,附源碼)

 


十大經典排序算法(java實現、配圖解,附源碼)

 

6.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

6.3實例展示

 1 import java.util.Arrays;
 2 public class ShellSort {
 3     public static void main(String[] args) {
 4         int[] array = new int[]{15,63,97,12,235,66};
 5 
 6 //        實現增量變化
 7         for (int gap = array.length/2;gap>0;gap/=2){
 8 
 9             for (int i=gap;i<array.length;i++){
10 
11                 for (int j=i-gap;j>=0;j-=gap){
12                     if (array[j]>array[j+gap]){
13                         int temp = 0;
14                         temp = array[j];
15                         array[j] = array[j+gap];
16                         array[j+gap] = temp;
17                     }
18                 }
19             }
20         }
21         System.out.println(Arrays.toString(array));
22     }
23 }
十大經典排序算法(java實現、配圖解,附源碼)

 


十大經典排序算法(java實現、配圖解,附源碼)

 

7.歸并排序

歸并排序(Merge Sort)是建立在歸并操作上的一種有效,穩定的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。

7.1實現原理

  • 第一步:申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合并后的序列
  • 第二步:設定兩個指針,最初位置分別為兩個已經排序序列的起始位置
  • 第三步:比較兩個指針所指向的元素,選擇相對小的元素放入到合并空間,并移動指針到下一位置重復步驟3直到某一指針超出序列尾將另一序列剩下的所有元素直接復制到合并序列尾
十大經典排序算法(java實現、配圖解,附源碼)

 

我們需要將兩個已經有序的子序列合并成一個有序序列,比如上圖最后一次合并,將[2,4,5,6]和[1,3,7,8]已經有序的子序列合并最終序列[1,2,3,4,5,6,7,8]

十大經典排序算法(java實現、配圖解,附源碼)

 

7.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

7.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 import java.util.Arrays;
 2 public class MSort {
 3     public static void main(String[] args) {
 4         int[] array = new int[]{15,63,97,12,235,66};
 5         //臨時數組
 6         int[] temp = new int[array.length];
 7         sort(array,0,array.length-1,temp);
 8         System.out.println(Arrays.toString(array));
 9 
10     }
11     public static void sort(int[] array,int left,int right,int[] temp){
12         if (left<right){
13 
14 //            求出中間值
15             int mid = (left+right)/2;
16 
17 //            向左邊分解
18             sort(array,left,mid,temp);
19 //            向右邊分解
20             sort(array,mid+1,right,temp);
21 //            合并數據
22             sum(array,left,right,mid,temp);
23         }
24     }
25     /**
26      * 合并元素
27      * @param array
28      * @param left
29      * @param right
30      * @param mid
31      * @param temp
32      */
33     public static void sum(int[] array,int left,int right,int mid,int[] temp){
34         int i = left;
35         int j = mid+1;
36 
37 //        指向臨時數組下標
38         int t = 0;
39 
40 //        開始循環比較左右兩遍數組元素比較
41         while (i<=mid && j<=right){
42 
43             if (array[i]<=array[j]){
44                 temp[t] = array[i];
45                 t++;
46                 i++;
47             }else {
48                 temp[t] = array[j];
49                 t++;
50                 j++;
51             }
52         }
53 
54 //        把剩余的元素直接存放在臨時數組中
55         while(i<=mid){
56             temp[t] = array[i];
57             t++;
58             i++;
59         }
60         while (j<=right){
61             temp[t] = array[j];
62             t++;
63             j++;
64         }
65 
66 //        臨時數組中的元素拷貝至原數組中
67         int tempIndex = left;
68         int k = 0;
69         while (tempIndex<=right){
70             array[tempIndex] = temp[k];
71             k++;
72             tempIndex++;
73         }
74     }
75 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

8.計數排序

計數排序是一個非基于比較的排序算法,該算法于1954年由 Harold H. Seward 提出。它的優勢在于在對一定范圍內的整數排序時,它的復雜度為Ο(n+k)(其中k是整數的范圍),快于任何比較排序算法。 當然這是一種犧牲空間換取時間的做法,而且當O(k)>O(n*log(n))的時候其效率反而不如基于比較的排序(基于比較的排序的時間復雜度在理論上的下限是O(n*log(n)), 如歸并排序,堆排序)

8.1實現原理

假設輸入的線性表L的長度為n,L=L1,L2,..,Ln;線性表的元素屬于有限偏序集S,|S|=k且k=O(n),S={S1,S2,..Sk};則計數排序可以描述如下:

  1. 掃描整個集合S,對每一個Si∈S,找到在線性表L中小于等于Si的元素的個數T(Si);
  2. 掃描整個線性表L,對L中的每一個元素Li,將Li放在輸出線性表的第T(Li)個位置上,并將T(Li)減1。
十大經典排序算法(java實現、配圖解,附源碼)

 

8.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

8.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 public class CountSort {
 2     public static void main(String[]args){
 3         //排序的數組
 4         int a[]={15,63,97,12,235,66};
 5         int b[]=countSort(a);
 6         for(int i:b){
 7             System.out.print( i+",");
 8         }
 9         System.out.println();
10     }
11     public static int[] countSort(int[]a){
12         int b[] = new int[a.length];
13         int max = a[0],min = a[0];
14         for(int i:a){
15             if(i>max){
16                 max=i;
17             }
18             if(i<min){
19                 min=i;
20             }
21         }//這里k的大小是要排序的數組中,元素大小的極值差+1
22         int k=max-min+1;
23         int c[]=new int[k];
24         for(int i=0;i<a.length;++i){
25             c[a[i]-min]+=1;//優化過的地方,減小了數組c的大小
26         }
27         for(int i=1;i<c.length;++i){
28             c[i]=c[i]+c[i-1];
29         }
30         for(int i=a.length-1;i>=0;--i){
31             b[--c[a[i]-min]]=a[i];//按存取的方式取出c的元素
32         }
33         return b;
34     }
35 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 


堆排序

堆排序(英語:Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。

9.1實現原理

  1. 創建一個堆 H[0……n-1];
  2. 把堆首(最大值)和堆尾互換;
  3. 把堆的尺寸縮小 1,并調用 shift_down(0),目的是把新的數組頂端數據調整到相應位置;
  4. 重復步驟 2,直到堆的尺寸為 1。
十大經典排序算法(java實現、配圖解,附源碼)

 

9.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

9.3實例展示

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 public static int[] heapSort(int[] array) {
 2         //這里元素的索引是從0開始的,所以最后一個非葉子結點array.length/2 - 1
 3         for (int i = array.length / 2 - 1; i >= 0; i--) {  
 4             adjustHeap(array, i, array.length);  //調整堆
 5         }
 6   
 7         // 上述邏輯,建堆結束
 8         // 下面,開始排序邏輯
 9         for (int j = array.length - 1; j > 0; j--) {
10             // 元素交換,作用是去掉大頂堆
11             // 把大頂堆的根元素,放到數組的最后;換句話說,就是每一次的堆調整之后,都會有一個元素到達自己的最終位置
12             swap(array, 0, j);
13             // 元素交換之后,毫無疑問,最后一個元素無需再考慮排序問題了。
14             // 接下來我們需要排序的,就是已經去掉了部分元素的堆了,這也是為什么此方法放在循環里的原因
15             // 而這里,實質上是自上而下,自左向右進行調整的
16             adjustHeap(array, 0, j);
17         }
18         return array;
19     }
20   
21     /**
22     * 整個堆排序最關鍵的地方
23     * @param array 待組堆
24     * @param i 起始結點
25     * @param length 堆的長度
26     */
27     public static void adjustHeap(int[] array, int i, int length) {
28         // 先把當前元素取出來,因為當前元素可能要一直移動
29         int temp = array[i];
30         for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {  //2*i+1為左子樹i的左子樹(因為i是從0開始的),2*k+1為k的左子樹
31             // 讓k先指向子節點中最大的節點
32             if (k + 1 < length && array[k] < array[k + 1]) {  //如果有右子樹,并且右子樹大于左子樹
33                 k++;
34             }
35             //如果發現結點(左右子結點)大于根結點,則進行值的交換
36             if (array[k] > temp) {
37                 swap(array, i, k);
38                 // 如果子節點更換了,那么,以子節點為根的子樹會受到影響,所以,循環對子節點所在的樹繼續進行判斷
39                     i  =  k;
40                         } else {  //不用交換,直接終止循環
41                 break;
42             }
43         }
44     }
45   
46     /**
47     * 交換元素
48     * @param arr
49     * @param a 元素的下標
50     * @param b 元素的下標
51     */
52     public static void swap(int[] arr, int a, int b) {
53         int temp = arr[a];
54         arr[a] = arr[b];
55         arr[b] = temp;
56     }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

10.桶排序

桶排序 (Bucket sort)或所謂的箱排序,是一個排序算法,工作的原理是將數組分到有限數量的桶子里。每個桶子再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序)。桶排序是鴿巢排序的一種歸納結果。當要被排序的數組內的數值是均勻分配的時候,桶排序使用線性時間(Θ(n))。但桶排序并不是 比較排序,他不受到 O(n log n) 下限的影響。

10.1實現原理

假定:輸入是由一個隨機過程產生的[0, 1)區間上均勻分布的實數。將區間[0, 1)劃分為n個大小相等的子區間(桶),每桶大小1/n:[0, 1/n), [1/n, 2/n), [2/n, 3/n),…,[k/n, (k+1)/n ),…將n個輸入元素分配到這些桶中,對桶中元素進行排序,然后依次連接桶輸入0 ≤A[1..n] <1輔助數組B[0..n-1]是一指針數組,指向桶(鏈表)。

十大經典排序算法(java實現、配圖解,附源碼)

 

10.2 動圖演示

十大經典排序算法(java實現、配圖解,附源碼)

 

然后,元素在每個桶中排序:

十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

 1 public static void basket(int data[])//data為待排序數組
 2 {
 3 int n=data.length;
 4 int bask[][]=new int[10][n];
 5 int index[]=new int[10];
 6 int max=Integer.MIN_VALUE;
 7 for(int i=0;i<n;i++)
 8 {
 9 max=max>(Integer.toString(data[i]).length())?max:(Integer.toString(data[i]).length());
10 }
11 String str;
12 for(int i=max-1;i>=0;i--)
13 {
14 for(int j=0;j<n;j++)
15 {
16 str="";
17 if(Integer.toString(data[j]).length()<max)
18 {
19 for(int k=0;k<max-Integer.toString(data[j]).length();k++)
20 str+="0";
21 }
22 str+=Integer.toString(data[j]);
23 bask[str.charAt(i)-'0'][index[str.charAt(i)-'0']++]=data[j];
24 }
25 int pos=0;
26 for(int j=0;j<10;j++)
27 {
28 for(int k=0;k<index[j];k++)
29 {
30 data[pos++]=bask[j][k];
31 }
32 }
33 for(intx=0;x<10;x++)index[x]=0;
34 }
35 }
十大經典排序算法(java實現、配圖解,附源碼)

 

排序結果展示:

十大經典排序算法(java實現、配圖解,附源碼)

 

總結:

以上便是本篇文章所寫的關于十大經典排序算法所有內容了,碼字不易,對你有幫助的話,請給個三連(關注、點贊、收藏)有問題可評論區留言討論。
原文鏈接:
https://www.cnblogs.com/zbcxy506/p/zbcxy506_3arithmetic-01.html

分享到:
標簽:算法 排序
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定