數組是一個定長的容器,能夠放相同類型的數據。
數組中的元素能夠是任何數據類型,包括基本數據類型和引用數據類型程序員
數組(Array)是一種線性表數據結構。它用一組連續的內存空間,來存儲一組具備相同類型的數據。
線性表,顧名思義,線性表就是數據排成像一條線同樣的結構。每一個線性表上的數據最多隻有前和後兩個方向。
數組具備連續的內存空間和相同的數據類型編程
dataType[] arrayName;
注:數組在聲明時不能指定數組長度,即dataType[n] arrayName;是不合法的數組
arrayName = new dataType[n];數據結構
dataType[] arrayName = new dataType[n];dom
dataType[] arrayName = new dataType[]{value1,value2,......,valueN};ide
數組的聲明即數組變量名存儲在棧中,數組的建立在堆中,即在堆中開闢連續的對應數組長度的空間(全部引用類型的建立都在堆中)
全部引用類型的變量名存的都是地址。學習
引用類型的數組元素默認初始值是null
字符類型的數組元素默認初始值是空格(0對應的字符)
整數類型的數組元素默認初始值是0
浮點數類型的元素默認初始值是0.0
布爾類型的元素默認初始值是false 優化
從數組存儲的內存模型上來看,「下標」最確切的定義應該是「偏移(offset)」。若是用 a 來表示數組的首地址,a[0] 就是偏移爲 0 的位置,
也就是首地址,a[k] 就表示偏移 k 個 type_size 的位置,因此計算 a[k] 的內存地址只須要用這個公式:設計
a[k]_address = base_address + k * type_sizecode
可是,若是數組從 1 開始計數,那咱們計算數組元素 a[k] 的內存地址就會變爲:
a[k]_address = base_address + (k-1)*type_size
對比兩個公式,咱們不難發現,從 1 開始編號,每次隨機訪問數組元素都多了一次減法運算,對於 CPU 來講,就是多了一次減法指令。數組做爲很是基礎的數據結構,經過下標隨機訪問數組元素又是其很是基礎的編程操做,效率的優化就要儘量作到極致。因此爲了減小一次減法操做,數組選擇了從 0 開始編號,而不是從 1 開始。
也有多是歷史緣由
C 語言設計者用 0 開始計數數組下標,以後的 Java、JavaScript 等高級語言都效仿了 C 語言,或者說,爲了在必定程度上減小 C 語言程序員學習 Java 的學習成本,所以繼續沿用了從 0 開始計數的習慣。實際上,不少語言中數組也並非從 0 開始計數的,好比 Matlab。甚至還有一些語言支持負數下標,好比 Python。
鏈表適合插入和刪除,時間複雜度是O(1),數組支持隨機訪問,根據下標隨機訪問的時間複雜度爲O(1)。
按照數組下標順序,依次將冒號右邊數組中的每一個元素賦值給冒號左邊的變量,數組長度爲for循環的次數
for(數組元素類型 變量名 : 數組名){
語句;
}
編寫一個長度爲5的整型數組,每一個元素賦值爲0-10的隨機整數,遍歷該數組,輸出每一個元素。
int[] arr = new int[5];
Random r = new Random();
for(int i = 0; i < arr.length; i++){
arr[i] = r.nextInt(10);
}
for(int t : arr){
System.out.println(t);
}
數據類型是數組的數組
數組名 = new 數據元素類型[ 行數 ] [ 列數 ] ;
行數不能爲空
數組類型 數組名[ ][ ] = new 數據類型[ ][ ] { {元素11,元素12,…} , {元素21,… } }
int[] arr = new int[]{4,45,1,13,89,7}; int temp; for(int i = 0; i < arr.length; i++){ for(int j = 0; j < arr.length - 1;j++){ if(arr[j] > arr[j+1]){ temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }
int[] arr = new int[]{4,45,1,13,89,7}; int temp; boolean flag = false; for(int i = 0; i < arr.length; i++){ for(int j = 0; j < arr.length - i -1;j++){ if(arr[j] > arr[j+1]){ temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; flag = true; } } //當沒有數據交換時,證實數組已排序完成,退出子循環 if(!flag){ break; } }
Random r = new Random(); int[][] arr = new int[4][6]; for(int i = 0; i < arr.length; i++){ for(int j = 0; j < arr[0].length;j++){ arr[i][j] = r.nextInt(100); System.out.print(arr[i][j]+" "); } System.out.println(); } int row = arr.length; int column = arr[0].length;
//二維數組轉化爲一維數組 int[] array = new int[row * column]; for(int i = 0; i < row; i++){ for(int j = 0; j < column; j++){ array[i*column+j] = arr[i][j]; } } //對一維數組進行冒泡排序 int temp; boolean flag = false; for(int i = 0; i < array.length; i++){ for(int j = 0; j < array.length - i -1;j++){ if(array[j] > array[j+1]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; flag = true; } } if(!flag){ break; } } //輸出排序後的一維數組 for(int i : array){ System.out.print(i + " "); } System.out.println(); //將排序後的一維數組轉化爲二維數組 for(int i = 0; i < row; i++){ for(int j = 0; j < column; j++){ arr[i][j] = array[i*column+j]; } } //輸出二維數組 for(int i = 0 ; i < arr.length;i++){ System.out.println(Arrays.toString(arr[i])); }
int temp = 0; boolean flag = false; //全部子數組完成排序須要的冒泡次數總和 for(int t = 0; t < row * column; t++){ //遍歷父數組,即第一維數組(行)的遍歷 for(int z = 0; z < arr.length; z++){ //每一個數組完成排序須要的冒泡次數 for(int i = 0; i < arr[0].length; i++){ //遍歷子數組,並進行冒泡排序 for(int j = 0; j < arr[0].length - 1 -i; j++){ if(arr[z][j]>arr[z][j+1]){ temp = arr[z][j]; arr[z][j] = arr[z][j+1]; arr[z][j+1] = temp; flag = true; } } //當沒有數據交換時,證實數組已排序完成,退出子循環 if(!flag){ break; } } //輸出每組的最大值 //System.out.println(arr[z][arr[0].length-1]); //將每組的最大值與下一組的第一個值比較,若大於則交換 if(z < arr.length - 1 && arr[z][arr[0].length-1] > arr[z+1][0]){ temp = arr[z][arr[0].length-1]; arr[z][arr[0].length-1] = arr[z+1][0]; arr[z+1][0] = temp; } } } //輸出二維數組 for(int i = 0 ; i < arr.length;i++){ System.out.println(Arrays.toString(arr[i])); }