將一陣列亂序排列的三種方法
阿新 • • 發佈:2019-02-10
方法一,最笨的菜鳥方法,也是容易想到的(幸好我沒想過這種方法 :))
從已知陣列中隨機一個數,然後加入到另一個數組中,在加入之前,先檢查是否已經加入過。
這種方法有很大運氣成分,且資料越大,效率越低,超過一定數目,則程式幾乎無法執行,會一直卡在那裡,程式碼:
- package com.test;
- import java.util.Random;
- publicclass TestArray {
- publicstaticint runCount =0;//用於記錄方法運算次數
- publicint [] m1(int [] arr){
- Random ran = new Random();
- int length = arr.length;
- int [] newArr = newint[length];
- int count =0;
- while (true) {
- runCount ++;
- int r = ran.nextInt(length)+1;
- if(!exist(r, newArr)){
- newArr [count] = r;
- count++;
- }
- if(count==length){
- break;
- }
- }
- System.out.println("m1 運算次數 = "
- return newArr;
- }
- publicstaticboolean exist(int a,int [] arr){
- for (int i = 0; i < arr.length; i++) {
- if(arr[i] ==a){
- returntrue;
- }
- }
- returnfalse;
- }
方法二,這種方法是我遇到這個問題就想到的,思路就是:先隨機出已知陣列的下標值,然後取出這個數放到另一個數組中,再從已知陣列中刪除這個數。這種方法的運算次數是根據陣列長度而定的,缺點是 大部分運算都耗在刪除的判斷上,主要是因為 陣列不像list那樣,能刪除一個指定位置的值。程式碼:
- //-----------------------------------------------
- publicint [] m2(int [] arr){
- Random ran = new Random();
- int [] newArr = newint[arr.length];
- int k = 0;
- while (arr.length>0) {
- runCount++;
- int index = ran.nextInt(arr.length);//隨即陣列下標
- newArr[k++] = arr[index];
- arr = removeElement(arr[index], arr);
- }
- System.out.println("m2運算次數 = "+runCount);
- return newArr;
- }
- publicint [] removeElement(int ele,int [] arr){
- int [] arr2 =newint[arr.length-1];
- int k = 0;
- for (int i = 0; i < arr.length; i++) {
- runCount++;
- if(arr[i]!=ele){
- arr2[k++] = arr[i];
- }
- }
- return arr2;
- }
方法三, 這種方法就很巧妙了,是在c 的程式碼中看到,翻譯成了java程式碼,它的巧妙在於:每次從已知陣列隨機一個數,然後將陣列的最後一個值 賦值給前面隨機到的數的位置上,然後將長度-1,再從原陣列下標-1的陣列中隨機。 運算次數就是陣列長度,這種方法真的很聰明啊,以下是程式碼:
- //-----------------------------------------------
- publicint [] m3(int [] arr) {
- int [] arr2 =newint[arr.length];
- int count = arr.length;
- int cbRandCount = 0;// 索引
- int cbPosition = 0;// 位置
- int k =0;
- do {
- runCount++;
- Random rand = new Random();
- int r = count - cbRandCount;
- cbPosition = rand.nextInt(r);
- arr2[k++] = arr[cbPosition];
- cbRandCount++;
- arr[cbPosition] = arr[r - 1];// 將最後一位數值賦值給已經被使用的cbPosition
- } while (cbRandCount < count);
- System.out.println("m3運算次數 = "+runCount);
- return arr2;
- }
測試下程式碼:
- // ----------------------------------------------
- publicstaticvoid main(String[] args) {
- int[] arr = newint[10];
- for (int i = 0; i < arr.length; i++) {
- arr[i] = i + 1;
- }
- TestArray t = new TestArray();
- arr = t.m1(arr);
- print(arr);
- arr = t.m2(arr);
- print(arr);
- arr = t.m3(arr);
- print(arr);
- }
- publicstaticvoid print(int[] arr) {
- for (int i = 0; i < arr.length; i++) {
- System.out.print(arr[i] + " ");
- }
- System.out.println();
- runCount = 0;
- }
結果:
- m1 運算次數 = 51
- 31021596847
- m2運算次數 = 65
- 13821059674
- m3運算次數 = 10
- 10783156924
第三種方法還是值得學習的,大家如果有其它好的方法和思路歡迎補充~~