[2018/11/17] Java数据结构(1)数组
最近在网上下载了一个关于java数据结构的视频感觉讲得非常的好, 写几篇博文总结一下.
分享链接 https://pan.baidu.com/s/1AT4OQ9wJsBNm4FDlqvziUQ 提取码: 9vbb
代码:
1 package ch_01; 2 3 public class MyArray { 4 private long[] arr; 5 private int elements; 6 7 /** 8 * 初始化数组 9 */ 10 public MyArray() { 11 arr = new long[50]; 12 } 13 14 /** 15 * 重构初始化函数, 自定义函数的长度 16 * @param maxsize 17 */ 18 public MyArray(int maxsize) { 19 arr = new long[maxsize]; 20 } 21 22 /** 23 * 插入数组的元素 24 */ 25 public void insert(long value) { 26 /*由于数组的最末一项的编号是elements-1, 所以可以直接通过elements来表示新加入的元素*/ 27 arr[elements] = value; 28 elements++; // 注意elements要后移一位, 方便下一次添加元素. 29 } 30 31 /** 32 * 显示数组的元素 33 */ 34 public void display() { 35 System.out.print("["); 36 for (int i = 0; i < elements; i++) { 37 System.out.print(arr[i] + " "); 38 } 39 System.out.println("]"); 40 } 41 42 /** 43 * 按照数组值搜索 44 */ 45 public int search(long value) { 46 int i; 47 for (i = 0; i < elements; i++) { 48 if (value == arr[i]) { 49 break; 50 } 51 } 52 53 if(i == elements) { 54 // 如果遍历到最后一个序列, 注意最后一个元素的序列因该是elements-1 55 return -1; 56 } else { 57 return 1; 58 } 59 } 60 61 /** 62 * 按序列获取元素值 63 */ 64 public long get(int index) { 65 if (index >= elements || index < 0) { 66 throw new ArrayIndexOutOfBoundsException(); 67 } else { 68 return arr[index]; 69 } 70 } 71 72 /** 73 * 删除数据 74 */ 75 public void delete(int index) { 76 if(index >= elements || index < 0) { 77 throw new ArrayIndexOutOfBoundsException(); 78 } else { 79 for(int i = index; i < elements; i++) { 80 arr[i] = arr[i + 1]; //写错了, 之前写成了arr[index] = arr[index + 1] 81 //抹掉index序列的元素的值, 后面的元素整体向前移动 82 } 83 elements--; // 处理后, 要将元素的数量减一 84 } 85 } 86 }
这个类定义了两个构造方法, 5个方法, 两个私有的变量.
不带参数的构造方法创建了一个长度为50的数组变量. 带参数的构造方法创建了一个数组变量, 数组的长度是参数的大小.
其他的五个方法的功能包括: 插入一个元素(insert)、显示所有的元素(display)、按值搜索数组内的元素(search)、获取一个元素(get)、删除一个元素(delete)
两个私有的变量分别是long型的数组变量arr, 还有long型的变量elements, elements变量没有赋值, 自动初始化为0, 这个变量用来表示数组的数量.
通过debug分析代码, 逐个分析一下方法的功能的实现.
- 插入一个数组元素的方法insert
1 public void insert(long value) { 2 /*由于数组的最末一项的编号是elements-1, 所以可以直接通过elements来表示新加入的元素*/ 3 arr[elements] = value; 4 elements++; // 注意elements要后移一位, 方便下一次添加元素. 5 }
elements初始化为0, 正好对应数组第一个元素的下标为零. arr[elements] = value; 这一句实现了插入元素的功能, elements++; elements变量自增, 为下一次添加元素做好准备.
- 显示所有的元素(display)
1 /** 2 * 显示数组的元素 3 */ 4 public void display() { 5 System.out.print("["); 6 for (int i = 0; i < elements; i++) { 7 System.out.print(arr[i] + " "); 8 } 9 System.out.println("]"); 10 }
这个方法不带有参数和返回值, 主体的内容是一个for循环, 循环变量i的范围是[0, elements)的整数, 我们可以发现, 数组对映的下标就是[0, elements-1], 由于循环变量的数据类型是i所以[0, elemtents) 等价于[0, elements-1]. 因此这个循环语句遍历了数组变量arr的每一个元素. 然后就是简单的输出语句.
- 按数组值搜索
1 /** 2 * 按照数组值搜索 3 */ 4 public int search(long value) { 5 int i; 6 for (i = 0; i < elements; i++) { 7 if (value == arr[i]) { 8 break; 9 } 10 } 11 12 if(i == elements) { 13 // 如果遍历到最后一个序列, 注意最后一个元素的序列因该是elements-1 14 return -1; 15 } else { 16 return 1; 17 } 18 }
该方法传入一个long型的参数, 返回一个int型的值. 主体的内容是一个for循环, 还有一个if判断语句. for循环的功能是循环遍历数组内的所有的元素, 如果数组内的元素的值和输入的参数相等, 那么就停止遍历, 并记录下循环的次数.下面的if判断语句用来判断循环的次数是否等于elements, 如果是, 那么就返回-1, 表示查询失败. 否则, 返回1, 表示成功查询到了. 这里要注意为什么i==elements表示查询失败呢? 我们可以设想, 如果我们想要的值是最后一个数组元素. 那么那时的i等于多少呢? 是elements-1, 因为 break; , 我们找到该值的时候就立马退出for循环, 此时for循环不是因为i=elements, 从而不满足for循环的上限 i < elements; 而退出循环. 故我们可以知道, 当i=elements时, for 循环是因为数组内没有想要的元素, 从而完整的遍历了数组的所有的变量, 然后退出的.
-
按序列获取元素值get
1 /** 2 * 按序列获取元素值 3 */ 4 public long get(int index) { 5 if (index >= elements || index < 0) { 6 throw new ArrayIndexOutOfBoundsException(); 7 } else { 8 return arr[index]; 9 } 10 }
这个方法传入一个lint型的参数, 返回一个long型的值. int型的参数用来指代想要的数组元素的序列, 这个方法很简单, 主体是一个if...else...语句. 意思是, 如果输入的整型的参数不在[0, elements)范围内, 就报错, 反之, 就直接返回下标为传入参数的数组元素的值. 功能很简单, 但是这个方法给了我提示, 数组的功能真是强大, 可以直接通过下标取得元素的值, 这是值得总结的小技巧. 还有需要思考的是, 为什么不用if (index >= 0 && index < elements) { return arr[index]; }, 将报错写在else语句内. 感觉是一样的, 以后再想区别吧.
- 最后是删除一个数组元素delete
1 /** 2 * 删除数据 3 */ 4 public void delete(int index) { 5 if(index >= elements || index < 0) { 6 throw new ArrayIndexOutOfBoundsException(); 7 } else { 8 for(int i = index; i < elements; i++) { 9 arr[i] = arr[i + 1]; //写错了, 之前写成了arr[index] = arr[index + 1] 10 //抹掉index序列的元素的值, 后面的元素整体向前移动 11 } 12 elements--; // 处理后, 要将元素的数量减一 13 } 14 }
传入一个int型参数, 无返回值. 传入的参数表示数组元素的下标, 同样的这个方法的主体部分是一个if...else...判断语句, 首先判断输入的整型参数是否在[0, elements-1)范围内, 如果不在, 就报错. 如果在的话, 通过一个for循环, 将该元素删除, 循环结束后再将elements减1. 具体如何通过for循环实现删除下标为参数的元素的功能的呢? 具体是从i=参数开始循环, 直到i=elemtents-1为止, 即数组元素的下标为参数开始到数组元素的最后一个元素. 都将后一个元素的值赋给前一个元素, 最后再将记录元素数量的变量elements减1, 从而实现删除具体先表的元素的功能.
测试类:
1 package ch_01; 2 3 public class TestArray { 4 5 /** 6 * 测试类 7 * @param args 8 */ 9 10 public static void main(String[] args) { 11 12 MyArray arr = new MyArray(); 13 arr.insert(10); 14 arr.insert(20); 15 arr.insert(90); 16 arr.display(); 17 System.out.println(arr.search(20)); 18 System.out.println(arr.get(2)); 19 arr.delete(0); 20 arr.display(); 21 } 22 23 }
这套教材让我开始不再把所有的内容都写在一个Main.class内. 感觉很棒!!!!!