不知不覺大學過了三年,最遺憾的就是在大二沒把《數據結構》和《算法》這兩門課程學好~~~算法
如今天天花一點時間把這兩個內容回顧一下,算是給本身的一點目標吧!數組
<1>數組(Array):數據結構
數組算是最簡單的也是最基本的結構之一。在Java中,咱們聲明一個數組有兩種形式:dom
int[] array = { 1, 2, 3 };性能
或spa
int array[] = { 1, 2, 3 };設計
這兩種形式都是能夠的,但推薦第一種,爲何呢?3d
首先,int[]和int是兩種徹底不一樣的類型!int是原生數據類型(Primitive Data Type)而int[]是引用數據類型(Reference Type)。好比像上面的array,它是有屬性(Field)有方法(Method)的。第一種直接在語法上看,array就是一種新的類型,第二種應該是爲了和C語言拉近關係而引入的。code
數組的元素類型必須是一致而且長度是固定的。爲何呢?對象
這應該是與數組在設計時的目標有關。數組有一個特色就是能夠隨機訪問(Random Access)。而所謂的隨機訪問是指能夠快速的訪問數組的任一元素,怎麼作到的?數組在內存中是連續存儲的,因此咱們只要知道數組的首地址和每一個元素佔用多大的內存空間咱們就能夠算出任意元素的具體位置。由於這兩點,數組必須是元素類型一致,而且長度固定的。
數組中的元素能夠是原生數據類型,也能夠是引用數據類型。這兩種的存儲形式是徹底不一樣的!一種存儲的是數據,一種存的是對象的地址。
假若有這樣兩個數組:
int[] array1 = { 1, 2, 3, 4 };和People[] array2 = { p1, p2, p3 };
那麼這二者的內存表示應該是這樣的:
這是一個比較重要也比較容易讓人迷惑的地方。數組元素能夠是引用!多維數組就是利用這一點實現的。也就是說,在Java中,實現上並無直接意義上的多維數組!咱們這樣理解:所謂的二維數組就是元素都是一維數組的一維數組。有點繞口,但確實是這樣的。
<2>數組的使用:
(1)冒泡排序
這個是比較簡單的排序,其基本思路是這樣的:
將相鄰兩個數據進行比較,若是左邊的值大於右邊的值,則將兩個值相互交換(所謂的大東西沉底~~~)。若是左邊的值小於右邊的值,則不變。而後右邊的值繼續比較。重複前面的過程。這樣完成一次以後就能夠把最大的值放到最右邊。重複執行直到排序完成。
來看具體代碼:
public int[] sort(int[] array) { // 先複製出一份 int[] result = array.clone(); for (int i = 0; i < result.length; i++) { for (int j = 0; j < result.length - 1; j++) { // 若是左邊的數大於右邊的數要進行兩數交換 if (result[j] > result[j + 1]) { int temp = result[j]; result[j] = result[j + 1]; result[j + 1] = temp; } } } return result; }
這段代碼運行是沒有問題的,但卻不是最好的。爲何呢?
首先,當咱們完成第一次遍歷的時候,最大的元素已經肯定。第二次的時候咱們還有必要讓最後兩個元素進行比較嗎?同理,進行完第二次的時候,第二大的數也已經肯定,不必在第三次的時候讓倒數第三個數和倒數第四個數進行比較。因此改進後是這樣的。
public int[] sort(int[] array) { // 先複製出一份 int[] result = array.clone(); for (int i = 0; i < result.length; i++) { // 減去i也就是最後肯定了幾個數了。 for (int j = 0; j < result.length - i - 1; j++) { // 若是左邊的數大於右邊的數要進行兩數交換 if (result[j] > result[j + 1]) { int temp = result[j]; result[j] = result[j + 1]; result[j + 1] = temp; } } } return result; }
就改動一個地方,但整個性能提升了一倍!
完整的代碼:
public class BubbleSort { public static void main(String[] args) { // 假定要進行排序的數組 int[] array = { 8, 7, 14, 8, 11, 12, 15, 1, 6 }; // 先打印出原數組 for (int i : array) { System.out.print(i + " "); } System.out.println("\n-----------------------------"); int[] result = sort(array); // 打印排序後的結果 for (int i : result) { System.out.print(i + " "); } } public static int[] sort(int[] array) { // 先複製出一份 int[] result = array.clone(); for (int i = 0; i < result.length; i++) { // 減去i也就是最後肯定了幾個數了。 for (int j = 0; j < result.length - i - 1; j++) { // 若是左邊的數大於右邊的數要進行兩數交換 if (result[j] > result[j + 1]) { int temp = result[j]; result[j] = result[j + 1]; result[j + 1] = temp; } } } return result; } }
(2)選擇排序:
算法的思路:
用一個數(int max)來記錄數組下標。先假定第一個數是最大的(max = 0),而後與後面的數進行比較,若是array[max]比後面的數小,則修改max的值爲比它大的數組元素的下標。這樣一次下來就能夠找出最大的數。而後放在數組後面就好了。
具體的代碼:
public class SelectionSort { public static void main(String[] args) { // 假定要進行排序的數組 int[] array = { 8, 7, 14, 8, 11, 12, 15, 1, 6 }; // 先打印出原數組 for (int i : array) { System.out.print(i + " "); } System.out.println("\n-----------------------------"); int[] result = sort(array); // 打印排序後的結果 for (int i : result) { System.out.print(i + " "); } } public static int[] sort(int[] array) { // 先複製出一份 int[] result = array.clone(); int max; for (int i = 0; i < result.length; i++) { // 每一次都默認第一個是最大的 max = 0; // 遍歷,找出最大值的下標 for (int j = 0; j < result.length - i; j++) { if (result[max] < result[j]) { max = j; } } // 進行值交換 int temp = result[result.length - i - 1]; result[result.length - i - 1] = result[max]; result[max] = temp; } return result; } }
冒泡和選擇的區別在於冒泡是找到大的就交換,而選擇是先找出最大值的下標,而後再交換。顯然,選擇排序的效率會高一些。運行結果都是相同的。