今天主要回顧一下數組方面的知識吧,有一維數組,二維數組,以及它們的經典應用。、
昨天一維數組的一些注意:
int[] arr = new int[]{5, 3, 7, 1, 8, 9, 2};
表示定義了一個元素類型為整型的數組,數組中的元素是 5,3,7,1,8,9,2,意味着數組的長度是 7。
數據類型[] 數組名 = {元素1,元素2,元素3,……};---不允許分開定義
數組的應用
1.操作指定位置上的元素:數組名[下標]
2.獲取數組長度:數組名.length;
3.遍歷數組,
(1)for(int i = 0; i < arr.length; i++){ System.out.println(arr[i]); } //與其說遍歷數組不如說遍歷下標 (2)for(int i : arr){ //arr[i] += 10; //只能遍歷數組但是不能改變數組中的值 System.out.println(i); } //增強 for 循環,此時的 i 依次表示數組中的每一個元素
4.獲取數組中最值(最大值/最小值)
方式一:定義變量來記錄數組中的最大值,然后遍歷數組,讓數組中的元素依次與最大值進行比較;如果大於最大值,則將這個元素覆蓋原來的最大值
方式二:定義變量來記錄最大值的下標。
//4.獲取數組中最值(最大值/最小值) //方式一:定義變量來記錄數組中的最大值,然后遍歷數組,讓數組中的元素依次與最大值進行比較;如果大於最大值,則將這個元素覆蓋原來的最大值 int max = arr[0]; for(int i : arr){ if(max < i){ max = i; } } System.out.println(max); //方式二:定義變量來記錄最大值的下標。 int flag = 0; for(int i = 1; i < arr.length; i++){ if(arr[flag] < arr[i]){ flag = i; } } System.out.println(arr[flag]);
5.數組的排序

(n-1)+(n-2)+(n-3)+……+2+1 = (n-1+1)(n-1)/2 = 1/2 n^2 - 1/2 n -> 1/2 n^2 -> O(n^2)
時間復雜度:在程序中找一段必然會執行的代碼,將這段代碼的執行時間認為是單位1,執行這個單位 1 需要的次數就是時間復雜度 -
時間復雜度不考慮系數,一般來說是找最高階 -> O(n^x),O((logn)^x),O(n^x(logn)^y) (決定的是效率,快慢程度)
空間復雜度:這段程序執行所需要額外耗費的空間就是空間復雜度
3個變量的空間 --- 3 = 3 * n^0 -> n^0 ->O(1) (占用的內存)
//冒泡排序 for(int i = 1; i < arr.length; i++){ //定義一個循環控制每一輪比較的次數 for(int j =1; j <= arr.length - i; j++){ if(arr[j -1] > arr[j]){ int temp = arr[j - 1]; arr[j - 1] = arr[j]; arr[j] = temp; } } } String str = Arrays.toString(arr); System.out.println(str);
就像是打擂台,摁住第一個不放跟后面的比較,下一步拿第二個跟后面的比較。(遇到小的就換掉)
5 1 7 0 8 2 6 比較的輪數:長度 - 1
每一輪選定的下標:輪數 - 1
每一輪比較的下標:輪數 ->最后一位
選定一位依次和其他位比較並排序 --- 選擇排序

時間復雜度:O(n^2) ->(n-2)+(n-3)+……+2+1 = (n-1)(n-2)/2=1/2 n^2+1/2 n -> O(n^2)
空間復雜度:O(1)
//選擇排序 //控制輪數 for(int i = 1; i < arr.length; i++){ //控制每一輪要比較的下標 for(int j = i; j < arr.length; j++){ if(arr[i - 1] > arr[j]){ int temp = arr[i - 1]; arr[i - 1] = arr[j]; arr[j] = temp; } } } //只能進行升序排序 //擴展:底層用的是快速排序 + 歸並排序 //時間復雜度:O(nlogn) Arrays.sort(arr); System.out.println(Arrays.toString(arr));
擴展:冒泡排序和選擇排序都是穩定的排序算法 --- 排序算法的穩定與否的依據是相等的元素在排序的時候是否需要交換
6.反轉數組:首尾互換 --- 時間復雜度O(n),空間復雜度O(1)
//反轉數組 //方式一: //時間復雜度:O(n),空間復雜度:O(n) int[] newArr = new int[arr.length]; for(int i = arr.length - 1, j = 0; i >= 0; i--,j++){ newArr[j] = arr[i]; } System.out.println(Arrays.toString(newArr)); //方式二:頭尾交換 //時間復雜度:O(n),空間復雜度 O(1) for(int i = 0, j = arr.length - 1; i <= j; i++, j--){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } System.out.println(Arrays.toString(arr));
7.數組元素的查找:
數組元素無序的前提下,獲取一個元素的位置只能通過遍歷的方式一一比較。(一個一個的找)
如果數組元素有序,使用二分查找 --- 空間復雜度 O(1),時間復雜度 O(logn)。
(1/2)x = n ->x = log1/2n = log2n/log21/2 ->log2n ->logn(默認底數為n)(每次折損 x 次,)
2x = n ->x = log2n ->logn(默認底數為n)
i
2 5 7 8 9 12 35 56 75 76 80 87 352
min mid max
mid max
arr[mid] ==i --- mid arr[mid] > i arr[mid] < i
8.數組的復制
System.arraycopy(要復制的數組,要復制的起始下標,存放的數組,要存放的起始下標,個數);
Arrays.copyOf(要擴容的數組, 擴容的大小); //用數組的復制可以實現數組的擴容
/數組的復制 //表示從 arr1 下標為 2 的位置上復制 4 個元素放入 arr2 數組中, //從 arr2 數組的下標為 4 的位置存放 int[] arr1 = {5,1,7,0,8,2,6}; int[] arr2 = new int[5]; System.arraycopy(arr1,2,arr2,0,4); System.out.println(Arrays.toString(arr2)); //數組的擴容 --- 數組的復制 --- 產生一個新的數組,導致擴容之后的數組和原數組不是同一個 int[] arr = {3,6,1,7,9}; int[] newArr = new int[8]; System.arraycopy(arr,0,newArr,0,arr.length); arr = newArr; arr = Arrays.copyOf(arr,8);//這一步等價於前面三步 System.out.println(Arrays.toString(arr));
二維數組
存儲的元素是一維數組 --- 存儲數組的數組(就像是一個大盒子里面有很多的小盒子)
定義格式
數據類型[][] 數組名 = new 數據類型[包含的一維數組的個數][每一個一維數組的長度];
int[ ][ ] arr = new int[3][5]; 表示定義了一個能存儲 3 個整型一維數組,每一個一維數組有 5 個整型元素
數據類型[ ][ ] 數組名 = new 數據類型[包含的一維數組的個數][];
int[ ][ ] arr = new int[5][ ]; 定義了一個能存儲 5 個整型一維數組的二維數組 --- 必須先保證這一位上的一維數組先給定大小,再給值
數據類型[ ][ ] 數組名 = {{數組1}, {數組2}, {數組3},…};
int[ ][ ] arr = {{2,4,1},{4,7,2,9},{3},{5,0,6,7,4,3}}; --- 二維數組的大小為 4
注意:[ ]如果在變量名之前那么緊跟着數據類型,也就意味着后面定義的變量是這個類型
數組的內存

練習:楊輝三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
特點:每一行的開始和結束都是1;其余位置的元素是計算:arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
輸入一個數字表示行數,輸出對應的前 n 行。
import java.util.Scanner; import java.util.Arrays; public class Demo{ public static void main(String[] args){ Scanner s = new Scanner(System.in); //定義行數 int n = s.nextInt(); //定義二維數組來存儲楊輝三角 int[][] arr = new int[n][]; //遍歷數組,向里填充元素 for(int i = 0; i < n; i++){ //先給每一個一維數組定義大小 arr[i] = new int[i + 1]; //遍歷一個一維數組,向里填充元素 for(int j = 0; j <= i; j++){ //判斷頭尾元素 if(j == 0 || j ==i){ arr[i][j] = 1; }else{ arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1]; } //填充完成之后打印這個填充的元素 System.out.print(arr[i][j]+"\t"); } System.out.println(); } //一個循環打印九九乘法表 for(int i = 1,j = 1;i <= 9; j++){ //無論哪一行,上來都是先打印* System.out.print("*"); //判斷是否打印完最后一個* if(j == i){ //換行 System.out.println(); //行數 +1 i++; // *從頭開始計數 j = 0; } } } }