3.1 数组的概述
数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
-
数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
-
创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
-
数组的长度一旦确定,就不能修改。
3.2 一维数组的使用
(1)声明方式:type var[] 或 type[] var; 如 int a[]; 和 int[] a;(栈内存)栈(stack):局部变量
(2)初始化:(堆内存)堆(heap):new出来的结构:对象、数组
-
Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法
-
动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行。
-
静态初始化:在定义数组的同时就为数组元素分配空间并赋值。int arr[] = new int[]{ 3, 9, 8}; 或 int[] arr = {3,9,8};
(3)引用:
-
每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)
-
数组一旦初始化,其长度是不可变的
(4)数组元素的默认初始化值:
-
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。
-
对于基本数据类型而言,默认初始化值各有不同
-
对于引用数据类型而言,默认初始化值为null(注意与0不同!)
3.3 多维数组的使用
对于二维数组的理解,我们可以看成是一维数组 array1 又作为另一个一维数组 array2 的元素而存 在。从数组底层的运行机制来看,并没有多维数组。
-
格式1(动态初始化):int[][] arr = new int[3][2]; //定义了名称为arr的二维数组 二维数组中有3个一维数组每一个一维数组中有2个元素。
-
格式2(动态初始化):int[][] arr = new int[3][]; //二维数组中有3个一维数组。每个一维数组都是默认初始化值null (注意:区别于格式1) 可以对这个三个一维数组分别进行初始化。
-
格式3(静态初始化):int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
-
注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。
3.4 数组中涉及到的常见算法
-
数组元素的赋值(杨辉三角、回形数等)
-
求数值型数组中元素的最大值、最小值、平均数、总和等
-
数组的复制、反转、查找(线性查找、二分法查找)
-
数组元素的排序算法。排序的目的是快速查找。
(1)衡量排序算法的优劣:
-
时间复杂度:分析关键字的比较次数和记录的移动次数
-
空间复杂度:分析排序算法中需要多少辅助内存
-
稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保 持不变,则称这种排序算法是稳定的。
(2)排序算法分类:内部排序和外部排序。
(3)十大内部排序算法:
-
选择排序:直接选择排序、堆排序
-
交换排序:冒泡排序、快速排序
-
插入排序:直接插入排序、折半插入排序、Shell排序
-
归并排序
-
桶式排序
-
基数排序
(4)各种内部排序方法性能比较:
-
从平均时间而言:快速排序最佳。但在最坏情况下时间性能不如堆排序和归并排序。
-
从算法简单性看:由于直接选择排序、直接插入排序和冒泡排序的算法比较简单,将其认为是简单算法。对于Shell排序、堆排序、快速排序和归并排序 算法,其算法比较复杂,认为是复杂排序。
-
从稳定性看:直接插入排序、冒泡排序和归并排序是稳定的;而直接选择排序、快速排序、 Shell排序和堆排序是不稳定排序 。
-
从待排序的记录数n的大小看:n较小时,宜采用简单排序;而n较大时宜采用改进排序。
(5)排序算法的选择:
-
若n较小(如n≤50),可采用直接插入或直接选择排序。当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插入,应选直接选择排序为宜。
-
若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排序为宜;
-
若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或 归并排序。
3.5 Arrays工具类的使用
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(如排序和搜索)的各种方法。
3.6 数组使用中的常见异常