javajavase
尚硅谷宋红康第3章_数组.pdf

概述
定义
- 数组(Array)是多个按一定顺序排列的相同类型数据的集合,使用一个名字命名,并通过编号的方式对这些数据进行统一管理
好处
- 同时存储多个数,代码简洁,而且提高了效率
- 分类存储,方便查找
概念
- 数组名:对一组具有相同数据类型的变量,使用一个名字来进行管理
- 元素:数组中的每一个数据
- 索引:数组的每一个元素,依靠下标,索引,编号进行区分
- 长度:数组的元素的总个数
注意
- 这一组具有相同数据类型的变量,在堆内存中开辟连续的空间
- 数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型
- 数组访问里面的元素 ,通过 数组名[下标], 下标:0——length-1
- 数组的长度一旦指定不能修改
一维数组
声明
type[] arr_name; //推荐使用此种方式type arr_name[];
- 声明一个数组的时候并没有数组真正被创建,并没有实例化任何对象
- 只有在实例化数组对象时JVM才分配空间,这时才与长度有关
- 构造一个数组,必须指定长度
初始化
- 静态初始化
```java //静态初始化基本类型数组 int[] a = int[]{1, 2, 3};type[] arr_name = new type[]{element1, element2, …};
//静态初始化引用类型数组 Student[] stu = Student[]{new Student(1, “张三”), new Student(2, “李四”)};
- **动态初始化**- 数组元素分配空间与赋值的操作分开进行```javatype[] arr_name = new type[length];arr_name[0] = element1;arr_name[1] = element2;…
int][] a = new int[2];//动态初始化数组,先分配空间a[0] = 1;//给数组元素赋值a[1] = 2;//给数组元素赋值
- 默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
- 整型:0
- 浮点型:0.0
- char型:0或’\u0000’,而非’0’
- boolean型:false
- 引用数据类型:null
长度:**数组名.length**
元素表示:**数组名[下标]**
- 数组元素下标的合法区间:[0, length-1],如果超过下标的范围,会报“数组下标越界ArrayIndexOutOfBoundsException”
遍历
for循环
for(int i=0; i<数组名.length; i++) {}
for-each循环
for(元素的数据类型 临时变量: 数组名) {}
String str = {"aa", "bb", "cc", "dd"};for (String temp: str) {System.out.println(temp);}
- 增强for循环是JDK1.5新增功能,专门用于读取数组或集合中所有的元素
内存解析
二维数组
声明
type[][] arr_name;
初始化
静态初始化
type[][] arr_name = {{element, element, …}, {element, element, …}, …};
int[][] a = {{1, 2, 3}, {3, 4}, {3, 5, 6, 7}}; //类型推断

动态初始化
规则
arr_name = new type[行数][列数];
- 总元素的个数是 行数*列数
- 每一行的列数相同的
- 不规则
```java 方式一 int[][] a = new int[3][]; a[0] = new int[2]; a[1] = new int[4]; a[2] = new int[3];arr_name = new type[行数][];
方式二 int[][] a = new int[3][]; //🔴 a[0] = {1, 2};//错误,没有声明就初始化,不能类型推断 a[0] = new int[]{1, 2}; a[1] = new int[]{3, 4, 5, 6}; a[2] = new int[]{7, 8, 9};
长度- 行数:`**二维数组名.length**`- 某一行的列数:`**arr_name[行标] .length**`元素的表示- 行对象:`**arr_name[行标]**`把二维数组如果看成一个一维数组,那么它的每一个元素就是一个行对象- 具体的元素:`**二维数组名[行标][列标]**`行标的范围:[0, 二维数组名.length)<br />列标的范围:[0, 二维数组名[i].length)<br />遍历- for```javafor(int i=0; i<array.length; i++) {for(int j=0; j<array[i].length; j++) {array[i][j]代表一个元素}}
- 增强for
```java
for(行对象的类型 行对象名: 二维数组名) {
for(元素的类型 临时变量: 行对象名) {
} }临时变量代表每一行中的某个具体元素
操作二维数组不应使用常数来控制维数。 具体方法是array.length表示行,array[row].length来表示row行的列数。 这样当数组每行行的列数不相等时,代码可以自动调整为正确的值
---<a name="xGIqF"></a>## 对象数组格式:```java引用类型[] 变量名;变量名 = new 引用类型[长度]; //开辟空间(指定长度)
赋值
- 先创建对象(也就是房间中打算放的内容)
**Student s = new Student();** - 将对象放到指定的数组某个空间中
**数组名[下标] = s;**
使用
循环打印
for(int i=0; i<数组名.length; i++) {数组名[i] .方法()/属性;}
循环判断
for(int i=0; i<数组名.length; i++) {if(数组名[i].属性 < max) {}}
数组常见异常
NullPointerException 空指针异常
ArrayIndexOutofBoundsException 数组下标越界
常见算法
赋值
- 杨辉三角 ```java // 1.声明并初始化二维数组 int[][] yangHui = new int[10][];
// 2.给数组的元素赋值 for(int i = 0; i < yangHui.length; i++) { yangHui[i] = new int[i + 1];
// 2.1 给首末元素赋值yangHui[i][0] = yangHui[i][i] = 1;// 2.2 给每行的非首末元素赋值for(int j = 1; j < yangHui[i].length - 1; j++) {yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];}
}
- 回行数求数组元素最大 最小 平均值 和<br />复制 反转 查找- 二分查找```java//前提:所要查找的数组必须有序。int[] arr = new int[]{-98,-34,2,34,54,66,79,105,210,333};int dest1 = -34;int head = 0;//初始的首索引int end = arr.length - 1;//初始的末索引boolean isFlag = true;while(head <= end) {int middle = (head + end)>>1;if(dest1 == arr[middle]) {System.out.println("找到了指定的元素,位置为:" + middle);isFlag = false;break;} else if(arr[middle] > dest1) {end = middle - 1;} else {head = middle + 1;}}if(isFlag) {System.out.println("很遗憾,没有找到的啦!");}
排序
- 衡量排序算法的优劣
- 时间复杂度:分析关键字的比较次数和记录的移动次数
- 空间复杂度:分析排序算法中需要多少辅助内存
- 稳定性:若两个记录A和B的关键字值相等,排序后A、B的先后次序保持不变,则称这种排序算法是稳定的
排序算法性能对比 | 排序方法 | 时间复杂度(平均) | 时间复杂度(最坏) | 时间复杂度(最好) | 空间复杂度 | 稳定性 | | —- | —- | —- | —- | —- | —- | | 插入 | O(n2) | O(n2) | O(n) | O(1) | 稳定 | | 希尔 | O(n1.3) | O(n2) | O(n) | O(1) | 不稳定 | | 选择 | O(n2) | O(n2) | O(n2) | O(1) | 不稳定 | | 堆 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 | | 冒泡 | O(n2) | O(n2) | O(n) | O(1) | 稳定 | | 快速 | O(nlogn) | O(n2) | O(nlogn) | O(nlogn) | 不稳定 | | 归并 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 | | 计数 | O(n+k) | O(n+k) | O(n+k) | O(n+k) | 稳定 | | 桶 | O(n+k) | O(n2) | O(n) | O(n+k) | 稳定 | | 基数 | O(n*k) | O(n*k) | O(n*k) | O(n+k) | 稳定 |
冒泡排序
public static void main(String[] args) {int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};//冒泡排序boolean isflag = true;for(int i = 0; i < arr.length - 1; i++) {for(int j = 0; j < arr.length - 1 - i; j++) {if(arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;isflag = false;}}if (isflag) {break;}}for(int i = 0; i < arr.length; i++) {System.out.print(arr[i] + "\t");}}
快速排序 ```java public static void quickSort(int[] data) { subSort(data, 0, data.length-1); }
private static void subSort(int[] data, int start, int end) { if (start < end) { int base = data[start]; int low = start; int high = end + 1;
while (true) {while (low < end && data[++low] - base <= 0);while (high > start && data[--high] - base >= 0);if (low < high) {swap(data, low, high);} else {break;}}swap(data, start, high);subSort(data, start, high - 1);//递归调用subSort(data, high + 1, end);}
}
private static void swap(int[] data, int i, int j) { int temp = data[i]; data[i] = data[j]; data[j] = temp; } ```
工具类Arrays
比较两个数组是否相等:**public static boolean equals(int[] a, int[] a2)**
输出数组信息,转成字符串**public static String toString(int[] a)**
字符串表示形式由数组的元素列表组成,括在方括号(“[]”)中。相邻元素用字符 “, “(逗号加空格)分隔
排序**public static void sort(int[] a)**
引用类型的数组排序需要java.lang.Comparable或java.util.Comparator接口的支持
查找**public static int binarySearch(int[] a, int key)**
a数组必须是排好序的
填充**public static void fill(int[] a, int value)**
给a数组的每一个元素填充为val**public static void fill(int[] a, int fromIndex, int toIndex, int value)**
给数组a中fromIndex到toIndex之间的元素填充为val
复制**public static int[] copyOf(int[] original, int newLength)**
复制original数组,得到一个新的数组,新的数组的长度是newLength
如果newLength**public static int[] copyOfRange(int[] original, int from, int to)**
从original数组的from开始复制到to这个部分的元素,产生一个新的数组
from必须在original数组的[0, original数组长度]范围之内
to可以在original数组下标范围内,也可以超过,如果超过,超过的部分使用默认值
转换为List
**public static <T> List<T> asList(T... a)**
System类中方法**static void arraycopy(object src,int srcpos,object dest, int destpos,int length)**
