1. 程式人生 > >陣列排序 及 二維陣列的拷貝

陣列排序 及 二維陣列的拷貝

多維陣列

 java 支援兩種資料型別的多維陣列。第一種是矩形陣列,也稱等長陣列。在二維矩形陣列中,每一行有相同的列數。例:int[][] A = new int[4][2];
java 支援的第二種多維陣列是交錯陣列,即所謂的正交陣列、變長陣列、鋸齒形陣列。在二維交錯陣列中,每一行可以有不同的列數。
 在多維陣列中,比較常用的是二維陣列。多維陣列的宣告、例項化和初始化與一維陣列的宣告、例項化和初始化相類似。宣告多維陣列時,用[]對錶示維數。兩個[]對錶示二維陣列,3個[]對錶示三維陣列,以此類推。
 基本資料型別的陣列未初始化的值均為 0 , 物件陣列 :初始化為null , Boolean:初始化預設為false,字串:/u0000。

  • 舉例:
package com.k;
import java.util.Arrays;
public class Yichang {
public static void  main(String[] args){
        int[][] array = {{1, 2, 3},{4, 5, 6}};
        int[][] brray = new int[2][3];
        int[][] arr1 = new int[2][3]; //宣告並建立一個二維整型陣列(2行3列)
        int[][] arr2 = {{1,2,3},{4,5
,6}}; //宣告並初始化一個二維整型陣列(2行3列,6個元素) int[][] arr3 = new int[][]{{1,2,3},{4,5,6}}; //宣告建立並初始化 int[][] arr4 = new int[3][]; arr4[0] = new int[2]; arr4[1] = new int[4]; arr4[2] = new int[5]; // 不規則陣列 System.out.println(Arrays.deepToString(brray)); System.
out.println(Arrays.deepToString(arr1)); System.out.println(Arrays.deepToString(arr2)); System.out.println(Arrays.deepToString(arr3)); System.out.println(Arrays.deepToString(arr4)); } }
[[0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [0, 0, 0]]
[[1, 2, 3], [4, 5, 6]]
[[1, 2, 3], [4, 5, 6]]
[[0, 0], [0, 0, 0, 0], [0, 0, 0, 0, 0]]

二維陣列的拷貝

 二維陣列的拷貝和一維陣列的拷貝類似,同樣有四種,分別是for迴圈拷貝,Object.clone(),System.arraycopy(),Arrays.copyOf() 四種拷貝方法。下面是程式碼示例:

  • for迴圈拷貝(淺拷貝)
package com.k;
import java.util.Arrays;
public class Yichang {
 public static void  main(String[] args){
        int[][] array = {{1, 2, 3},{4, 5, 6}};
        int[][] brray = new int[2][3];
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                brray[i][j] = array[i][j];
            }
        }
        System.out.println(Arrays.deepToString(brray));
    }
}
[[1, 2, 3], [4, 5, 6]]
class TestArray2 {
    private int val;
    public void setVal(int val) {
        this.val = val;
    }
    public int getVal() {
        return this.val;
    }
}

public class Yichang {
  public static void main(String[] args) {
        TestArray2[][] testArray2 = new TestArray2[2][2];
        testArray2[0][0] = new TestArray2();
        testArray2[0][1] = new TestArray2();
        testArray2[1][0] = new TestArray2();
        testArray2[1][1] = new TestArray2();
        TestArray2[][] testArray3 = new TestArray2[2][2];
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                testArray3[i][j] = testArray2[i][j];
            }
        }
        System.out.println("拷貝完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                System.out.print(testArray2[i][j].getVal() + " ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3.length; j++) {
                System.out.print(testArray3[i][j].getVal() + " ");
            }
        }
        System.out.println();
        testArray2[0][0].setVal(100);
        System.out.println("修改完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2[i].length; j++) {
                System.out.print(testArray2[i][j].getVal()+" ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3[i].length; j++) {
                System.out.print(testArray3[i][j].getVal()+" ");
            }
        }
        System.out.println();
    }
  }
拷貝完成
0 0 0 0 
0 0 0 0 
修改完成
100 0 0 0 
100 0 0 0 
  • ** Arrays.deepToString() 方法是多維陣列以字串形式輸出。**
  • Object.clone()
class TestArray2 {
    private int val;
    public void setVal(int val) {
        this.val = val;
    }
    public int getVal() {
        return this.val;
    }
}

public class Yichang {
  public static void main(String[] args) {
        TestArray2[][] testArray2 = new TestArray2[2][2];
        testArray2[0][0] = new TestArray2();
        testArray2[0][1] = new TestArray2();
        testArray2[1][0] = new TestArray2();
        testArray2[1][1] = new TestArray2();
        TestArray2[][] testArray3 = new TestArray2[2][2];
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
               testArray3[i] = testArray2[i].clone();
            }
        }
        System.out.println("拷貝完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2.length; j++) {
                System.out.print(testArray2[i][j].getVal() + " ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3.length; j++) {
                System.out.print(testArray3[i][j].getVal() + " ");
            }
        }
        System.out.println();
        testArray2[0][0].setVal(100);
        System.out.println("修改完成");
        for (int i = 0; i < testArray2.length; i++) {
            for (int j = 0; j < testArray2[i].length; j++) {
                System.out.print(testArray2[i][j].getVal()+" ");
            }
        }
        System.out.println();
        for (int i = 0; i < testArray3.length; i++) {
            for (int j = 0; j < testArray3[i].length; j++) {
                System.out.print(testArray3[i][j].getVal()+" ");
            }
        }
        System.out.println();
    }
  }
拷貝完成
0 0 0 0 
0 0 0 0 
修改完成
100 0 0 0 
100 0 0 0 
  • System.arraycopy():
 for (int i = 0; i < testArray2.length; i++) {
            System.arraycopy(testArray2[i], 0, testArray3[i], 0, testArray2[i].length);
        }
  • Arrays.copyOf():
 for (int i = 0; i < testArray2.length; i++) {
            testArray3[i] = Arrays.copyOf(testArray2[i], testArray2[i].length);
        }

匿名陣列

 使用陣列時,一般需要先宣告陣列變數,然後建立並初始化一個數組並賦值給宣告的陣列變數。Java語言也支援匿名陣列,即在需要陣列變數的地方,直接通過下列形式建立一個匿名陣列。

  • new 陣列型別[] {初始值設定項}; //建立一個一維匿名陣列
  • new 陣列型別[][] {初始值設定項};//建立一個二維匿名陣列

可變引數

 Java可變引數,適用於引數個數不確定,型別確定的情況,Java把可變引數當做陣列處理。
  可變引數使用時需要注意:
  1.只能出現在引數列表的最後;
  2.“…”位於變數型別和變數名之間,前後有無空格都可以;
   3.呼叫可變引數的方法時,編譯器為該可變引數隱含建立一個數組,在方法體中以陣列的形式訪問可變引數。

時間複雜度:

 一個演算法中的語句執行次數稱為語句頻度或時間頻度。記為T(n)。 時間複雜度,在剛才提到的時間頻度中,n稱為問題的規模,當n不斷變化時,時間頻度T(n)也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。 一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用T(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函式。記作T(n)=O(f(n)),稱O(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。
  按數量級遞增排列,常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n), 線性對數階O(nlog2n),平方階O(n2),立方階O(n3),…, k次方階O(nk),指數階O(2n)。隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低。

陣列的排序

  • 氣泡排序
  • 直接插入排序
  • 選擇排序

氣泡排序

 氣泡排序(Bubble Sort),又被稱為氣泡排序或泡沫排序。它是一種較簡單的排序演算法。它會遍歷若干次要排序的數列,每次遍歷時,它都會從前往後依次的比較相鄰兩個數的大小;如果前者比後者大,則交換它們的位置。這樣,一次遍歷之後,最大的元素就在數列的末尾! 採用相同的方法再次遍歷時,第二大的元素就被排列在最大元素之前。重複此操作,直到整個數列都有序為止!
 圖文舉例氣泡排序過程:陣列{20,40,30,10,60,50}排序
在這裡插入圖片描述

  • 舉例:
public class PaiXu {
    public static void MaoPao(int[] array){
        int tmp = 0;
        Boolean swap = true;
        for(int i = 0;i <= array.length-1; i++){
          for(int j = 0;j < array.length-1-i;j++){
              if(array[j] > array[j+1]){
                  tmp = array[j];
                  array[j] = array[j+1];
                  array[j+1] = tmp;
                  swap = true;
              }
          }
          if (!swap){
              break;  //氣泡排序及優化
          }
      }
    }
 public static void main(String[] args) {
        int[] array={2,1,5,10,3,8};
        MaoPao(array);
        System.out.println(Arrays.toString(array));
        }
}
[1, 2, 3, 5, 8, 10]
  • 氣泡排序時間複雜度
     最壞的時間複雜度為O(n^2),最好的時間複雜度為O(n)。
  • 氣泡排序的穩定性
     氣泡排序是穩定的演算法,它滿足穩定演算法的定義。
     演算法穩定性 – 假設在數列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;並且排序之後,a[i]仍然在a[j]前面。則這個排序演算法是穩定的!

直接插入排序

 直接插入排序(Straight Insertion Sort)的基本思想是:把n個待排序的元素看成為一個有序表和一個無序表。開始時有序表中只包含1個元素,無序表中包含有n-1個元素,排序過程中每次從無序表中取出第一個元素,將它插入到有序表中的適當位置,使之成為新的有序表,重複n-1次可完成排序過程。

  • 舉例: