1. 程式人生 > >將一陣列亂序排列的三種方法

將一陣列亂序排列的三種方法

方法一,最笨的菜鳥方法,也是容易想到的(幸好我沒想過這種方法 :))

從已知陣列中隨機一個數,然後加入到另一個數組中,在加入之前,先檢查是否已經加入過。

這種方法有很大運氣成分,且資料越大,效率越低,超過一定數目,則程式幾乎無法執行,會一直卡在那裡,程式碼:

  1. package com.test;  
  2. import java.util.Random;  
  3. publicclass TestArray {  
  4.  publicstaticint runCount =0;//用於記錄方法運算次數
  5.  publicint []  m1(int [] arr){  
  6.   Random ran = new Random();  
  7.   int length = arr.length;  
  8.   int [] newArr = newint[length];  
  9.   int count =0;  
  10.   while (true) {  
  11.    runCount ++;  
  12.    int r = ran.nextInt(length)+1;  
  13.    if(!exist(r, newArr)){  
  14.     newArr [count] = r;  
  15.     count++;  
  16.    }  
  17.    if(count==length){  
  18.     break;  
  19.    }  
  20.   }  
  21.   System.out.println("m1 運算次數  = "
    +runCount);  
  22.   return newArr;  
  23.  }  
  24.  publicstaticboolean exist(int a,int [] arr){  
  25.   for (int i = 0; i < arr.length; i++) {  
  26.    if(arr[i] ==a){  
  27.     returntrue;  
  28.    }  
  29.   }  
  30.   returnfalse;  
  31.  }  

方法二,這種方法是我遇到這個問題就想到的,思路就是:先隨機出已知陣列的下標值,然後取出這個數放到另一個數組中,再從已知陣列中刪除這個數。這種方法的運算次數是根據陣列長度而定的,缺點是 大部分運算都耗在刪除的判斷上,主要是因為 陣列不像list那樣,能刪除一個指定位置的值。程式碼:

  1. //-----------------------------------------------
  2. publicint []  m2(int [] arr){  
  3.  Random ran = new Random();  
  4.  int [] newArr = newint[arr.length];  
  5.  int k = 0;  
  6.  while (arr.length>0) {  
  7.   runCount++;  
  8.   int index = ran.nextInt(arr.length);//隨即陣列下標
  9.   newArr[k++] = arr[index];  
  10.   arr = removeElement(arr[index], arr);  
  11.  }  
  12.  System.out.println("m2運算次數  = "+runCount);  
  13.  return newArr;  
  14. }  
  15. publicint [] removeElement(int ele,int [] arr){  
  16.  int [] arr2 =newint[arr.length-1];  
  17.  int k = 0;  
  18.  for (int i = 0; i < arr.length; i++) {  
  19.   runCount++;  
  20.   if(arr[i]!=ele){  
  21.    arr2[k++] = arr[i];  
  22.   }  
  23.  }  
  24.  return arr2;  
  25. }  


 方法三, 這種方法就很巧妙了,是在c 的程式碼中看到,翻譯成了java程式碼,它的巧妙在於:每次從已知陣列隨機一個數,然後將陣列的最後一個值 賦值給前面隨機到的數的位置上,然後將長度-1,再從原陣列下標-1的陣列中隨機。 運算次數就是陣列長度,這種方法真的很聰明啊,以下是程式碼:

  1. //-----------------------------------------------
  2. publicint []  m3(int [] arr) {  
  3.  int [] arr2 =newint[arr.length];  
  4.  int count = arr.length;  
  5.  int cbRandCount = 0;// 索引
  6.  int cbPosition = 0;// 位置
  7.  int k =0;  
  8.  do {  
  9.   runCount++;  
  10.   Random rand = new Random();  
  11.   int r = count - cbRandCount;  
  12.   cbPosition = rand.nextInt(r);   
  13.   arr2[k++] = arr[cbPosition];  
  14.   cbRandCount++;  
  15.   arr[cbPosition] = arr[r - 1];// 將最後一位數值賦值給已經被使用的cbPosition
  16.  } while (cbRandCount < count);  
  17.  System.out.println("m3運算次數  = "+runCount);  
  18.  return arr2;  
  19. }  


測試下程式碼:

  1. // ----------------------------------------------
  2. publicstaticvoid main(String[] args) {  
  3.     int[] arr = newint[10];  
  4.     for (int i = 0; i < arr.length; i++) {  
  5.         arr[i] = i + 1;  
  6.     }  
  7.     TestArray t = new TestArray();  
  8.     arr = t.m1(arr);  
  9.     print(arr);  
  10.     arr = t.m2(arr);  
  11.     print(arr);  
  12.     arr = t.m3(arr);  
  13.     print(arr);  
  14. }  
  15. publicstaticvoid print(int[] arr) {  
  16.     for (int i = 0; i < arr.length; i++) {  
  17.         System.out.print(arr[i] + " ");  
  18.     }  
  19.     System.out.println();  
  20.     runCount = 0;  
  21. }  


結果:

  1. m1 運算次數  = 51
  2. 31021596847
  3. m2運算次數  = 65
  4. 13821059674
  5. m3運算次數  = 10
  6. 10783156924


第三種方法還是值得學習的,大家如果有其它好的方法和思路歡迎補充~~