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

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

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

1、冒泡排序

這個名詞的由來很好理解,一般河水中的冒泡,水底剛冒出來的時候是比較小的,隨著慢慢向水面浮起會逐漸增大,這物理規律我不作過多解釋,大家只需要了解即可。

冒泡算法的運作規律如下:

①、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

②、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最后一對。這步做完后,最后的元素會是最大的數(也就是第一波冒泡完成)。

③、針對所有的元素重復以上的步驟,除了最后一個。

④、持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

代碼如下:

  •  
package com.ys.sort;
 
public class BubbleSort {
 public static int[] sort(int[] array){
 //這里for循環表示總共需要比較多少輪
 for(int i = 1 ; i < array.length; i++){
 //設定一個標記,若為true,則表示此次循環沒有進行交換,也就是待排序列已經有序,排序已經完成。
 boolean flag = true;
 //這里for循環表示每輪比較參與的元素下標
 //對當前無序區間array[0......length-i]進行排序
 //j的范圍很關鍵,這個范圍是在逐步縮小的,因為每輪比較都會將最大的放在右邊
 for(int j = 0 ; j < array.length-i ; j++){
 if(array[j]>array[j+1]){
 int temp = array[j];
 array[j] = array[j+1];
 array[j+1] = temp;
 flag = false;
 }
 }
 if(flag){
 break;
 }
 //第 i輪排序的結果為
 System.out.print("第"+i+"輪排序后的結果為:");
 display(array);
 
 }
 return array;
 
 }
 
 //遍歷顯示數組
 public static void display(int[] array){
 for(int i = 0 ; i < array.length ; i++){
 System.out.print(array[i]+" ");
 }
 System.out.println();
 }
 
 public static void main(String[] args) {
 int[] array = {4,2,8,9,5,7,6,1,3};
 //未排序數組順序為
 System.out.println("未排序數組順序為:");
 display(array);
 System.out.println("-----------------------");
 array = sort(array);
 System.out.println("-----------------------");
 System.out.println("經過冒泡排序后的數組順序為:");
 display(array);
 }
}

結果如下:

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

本來應該是 8 輪排序的,這里我們只進行了 7 輪排序,因為第 7 輪排序之后已經是有序數組了。

冒泡排序解釋:

冒泡排序是由兩個for循環構成,第一個for循環的變量 i 表示總共需要多少輪比較,第二個for循環的變量 j 表示每輪參與比較的元素下標【0,1,......,length-i】,因為每輪比較都會出現一個最大值放在最右邊,所以每輪比較后的元素個數都會少一個,這也是為什么 j 的范圍是逐漸減小的。相信大家理解之后快速寫出一個冒泡排序并不難。

冒泡排序性能分析:

假設參與比較的數組元素個數為 N,則第一輪排序有 N-1 次比較,第二輪有 N-2 次,如此類推,這種序列的求和公式為:

  •  
(N-1)+(N-2)+...+1 = N*(N-1)/2

當 N 的值很大時,算法比較次數約為 N2/2次比較,忽略減1。

假設數據是隨機的,那么每次比較可能要交換位置,可能不會交換,假設概率為50%,那么交換次數為 N2/4。不過如果是最壞的情況,初始數據是逆序的,那么每次比較都要交換位置。

交換和比較次數都和N2 成正比。由于常數不算大 O 表示法中,忽略 2 和 4,那么冒泡排序運行都需要 O(N2) 時間級別。

其實無論何時,只要看見一個循環嵌套在另一個循環中,我們都可以懷疑這個算法的運行時間為 O(N2)級,外層循環執行 N 次,內層循環對每一次外層循環都執行N次(或者幾分之N次)。這就意味著大約需要執行N2次某個基本操作。私信我,回復:學習,獲取免費學習資源包。

2、選擇排序

選擇排序是每一次從待排序的數據元素中選出最小的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完。

分為三步:

①、從待排序序列中,找到關鍵字最小的元素

②、如果最小元素不是待排序序列的第一個元素,將其和第一個元素互換

③、從余下的 N - 1 個元素中,找出關鍵字最小的元素,重復(1)、(2)步,直到排序結束

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

代碼如下:

  •  
package com.ys.sort;
 
public class ChoiceSort {
 public static int[] sort(int[] array){
 //總共要經過N-1輪比較
 for(int i = 0 ; i < array.length-1 ; i++){
 int min = i;
 //每輪需要比較的次數
 for(int j = i+1 ; j < array.length ; j++){
 if(array[j]<array[min]){
 min = j;//記錄目前能找到的最小值元素的下標
 }
 }
 //將找到的最小值和i位置所在的值進行交換
 if(i != min){
 int temp = array[i];
 array[i] = array[min];
 array[min] = temp;
 }
 //第 i輪排序的結果為
 System.out.print("第"+(i+1)+"輪排序后的結果為:");
 display(array);
 }
 return array;
 }
 
 //遍歷顯示數組
 public static void display(int[] array){
 for(int i = 0 ; i < array.length ; i++){
 System.out.print(array[i]+" ");
 }
 System.out.println();
 }
 
 public static void main(String[] args){
 int[] array = {4,2,8,9,5,7,6,1,3};
 //未排序數組順序為
 System.out.println("未排序數組順序為:");
 display(array);
 System.out.println("-----------------------");
 array = sort(array);
 System.out.println("-----------------------");
 System.out.println("經過選擇排序后的數組順序為:");
 display(array);
 }
}

運行結果:

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

選擇排序性能分析:

選擇排序和冒泡排序執行了相同次數的比較:N*(N-1)/2,但是至多只進行了N次交換。

當 N 值很大時,比較次數是主要的,所以和冒泡排序一樣,用大O表示是O(N2) 時間級別。但是由于選擇排序交換的次數少,所以選擇排序無疑是比冒泡排序快的。當 N 值較小時,如果交換時間比選擇時間大的多,那么選擇排序是相當快的。

3、插入排序

直接插入排序基本思想是每一步將一個待排序的記錄,插入到前面已經排好序的有序序列中去,直到插完所有元素為止。

插入排序還分為直接插入排序、二分插入排序、鏈表插入排序、希爾排序等等,這里我們只是以直接插入排序講解,后面講高級排序的時候會將其他的。

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 


輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

代碼如下:

  •  
package com.ys.sort;
 
public class InsertSort {
 public static int[] sort(int[] array){
 int j;
 //從下標為1的元素開始選擇合適的位置插入,因為下標為0的只有一個元素,默認是有序的
 for(int i = 1 ; i < array.length ; i++){
 int tmp = array[i];//記錄要插入的數據
 j = i;
 while(j > 0 && tmp < array[j-1]){//從已經排序的序列最右邊的開始比較,找到比其小的數
 array[j] = array[j-1];//向后挪動
 j--;
 }
 array[j] = tmp;//存在比其小的數,插入
 }
 return array;
 }
 
 //遍歷顯示數組
 public static void display(int[] array){
 for(int i = 0 ; i < array.length ; i++){
 System.out.print(array[i]+" ");
 }
 System.out.println();
 }
 
 public static void main(String[] args){
 int[] array = {4,2,8,9,5,7,6,1,3};
 //未排序數組順序為
 System.out.println("未排序數組順序為:");
 display(array);
 System.out.println("-----------------------");
 array = sort(array);
 System.out.println("-----------------------");
 System.out.println("經過插入排序后的數組順序為:");
 display(array);
 }
}

運行結果:

 

輕松學習冒泡、選擇、插入排序算法(圖解)

 

 

插入排序性能分析:

在第一輪排序中,它最多比較一次,第二輪最多比較兩次,一次類推,第N輪,最多比較N-1次。因此有 1+2+3+...+N-1 = N*(N-1)/2。

假設在每一輪排序發現插入點時,平均只有全體數據項的一半真的進行了比較,我們除以2得到:N*(N-1)/4。用大O表示法大致需要需要 O(N2) 時間級別。

復制的次數大致等于比較的次數,但是一次復制與一次交換的時間耗時不同,所以相對于隨機數據,插入排序比冒泡快一倍,比選擇排序略快。

這里需要注意的是,如果要進行逆序排列,那么每次比較和移動都會進行,這時候并不會比冒泡排序快。

4、總結

上面講的三種排序,冒泡、選擇、插入用大 O 表示法都需要 O(N2) 時間級別。一般不會選擇冒泡排序,雖然冒泡排序書寫是最簡單的,但是平均性能是沒有選擇排序和插入排序好的。

選擇排序把交換次數降低到最低,但是比較次數還是挺大的。當數據量小,并且交換數據相對于比較數據更加耗時的情況下,可以應用選擇排序。

在大多數情況下,假設數據量比較小或基本有序時,插入排序是三種算法中最好的選擇。

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

網友整理

注冊時間:

網站: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

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