不知不觉大学过了三年,最遗憾的就是在大二没把《数据结构》和《算法》这两门课程学好~~~算法
如今天天花一点时间把这两个内容回顾一下,算是给本身的一点目标吧!数组
<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; } }
冒泡和选择的区别在于冒泡是找到大的就交换,而选择是先找出最大值的下标,而后再交换。显然,选择排序的效率会高一些。运行结果都是相同的。