概述
数组是多个相同数据类型按一定顺序排列的一组数据
特点:
- 数据类型相同!!
- 长度固定!!
构成数组的几个要素
- 数组名称
- 下标,又称索引
- 元素
- 数组长度
数组是一种引用类型,就像使用变量一样必须要有引用才能可控的访问
下标是数组的书签,访问数组的元素必须依靠下标
元素,数组所存储的数据,元素的数据类型必须和数组相同
长度,数组所存储的元素的个数
按维度分类,可以分为一维数组和多维数组
声明与初始化
package cn.dai; public class Arrays { public static void main(String[] args) { //声明一个数组 int[] array; // 初始化 array = new int[]{1,2,3,4,5,6,7}; // 如果简写,也就是静态初始化,必须 声明和初始化同时完成 int[] array2 = {2,3,4,5,7,8,9}; // 或者不对数组具体赋值元素而是初始化时声明数组的长度 int[] array3 = new int[10]; } }
访问元素和使用下标
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,3,5,7,9}; // 下标起始位置从0开始,结尾到数组的长度-1 System.out.println(array[0]); // 通过下标更改元素的值 array[3] = 10; } }
长度与遍历
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,3,5,7,9}; // 使用for循环遍历数组 length是数组的一个属性,表示数组的长度 for (int i = 0; i < array.length ; i++) { System.out.println( array[i] ); } } }
默认值?引用类型的属性问题
一维数组的内存分布图
多维数组
声明和初始化
package cn.dai; public class Arrays { public static void main(String[] args) { // 二维数组的初始化 静态 int[][] array = new int[][]{ {1,3,5,7,9}, {2,4,6,8,10} }; // 动态 二维数组可以只声明外围长度, // 内围数组没有声明就是未初始化的状态 // Java允许内围可以先不初始化 int[][] array2 = new int[4][]; } }
下标访问和遍历
package cn.dai; public class Arrays { public static void main(String[] args) { // 二维数组的初始化 静态 int[][] array = new int[][]{ {1,3,5,7,9}, {2,4,6,8,10} }; // 元素的访问 System.out.println(array[1][2]); // 遍历 // 先遍历外围长度,也就是内围的数组个数 for (int i = 0; i < array.length; i++) { // 再遍历下标指向的数组 for (int j = 0; j < array[i].length ; j++) { // 这样就能遍历每一个元素了 System.out.println( array[i][j] ); } } } }
数组练习
杨辉三角/帕斯卡三角
package cn.dai; public class Arrays { public static void main(String[] args) { // 杨辉三角形 外围的长度不限制 (不要低于5) int[][] pascalTriangle = new int[10][]; // 名字太长 声明一个简写引用一下 int[][] tri = pascalTriangle; for (int i = 0; i < tri.length; i++) { // 声明内围的数组 tri[i] = new int[i + 1]; // 连续赋值 每一行,也就是每一组数组的头和尾都是1 tri[i][0] = tri[i][i] = 1; // 对既不是头也不是尾的内部元素进行赋值 for (int j = 1; j < tri[i].length - 1 ; j++) { tri[i][j] = tri[i - 1][j - 1] + tri[i - 1][j]; } } // 打印查看 for (int i = 0; i < tri.length; i++) { for (int j = 0; j < tri[i].length; j++) { System.out.print(tri[i][j]+"\t"); } System.out.println(); } } }
一维数组:求最大最小值,平均值,总和
package cn.dai; public class Arrays { // 求最大值 static int getMaximum(int[] array){ // 设置游标 int max = array[0]; // 因为已经设置第一个赋值给了游标 从第二个开始遍历 for (int i = 1; i < array.length; i++) { // max = array[i] > max ? array[i] : max; max = Math.max(array[i], max); } return max; } // 求最小值 static int getMinimum(int[] array){ int min = array[0]; for (int i = 1; i < array.length; i++) { // min = array[i] < min ? array[i] : min; min = Math.min(array[i], min); } return min; } // 求和 static int getSummation(int[] array){ int sum = 0; for (int element : array) { sum += element; } return sum; } // 求平均值 static double getAverage(int[] array){ double sum = 0.0; for (int element : array) { sum += element; } return sum / array.length; } }
一维数组的复制
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,3,5,7,9}; // 先复制长度 int[] array2 = new int[array.length]; for (int i = 0; i < array2.length; i++) { // 复制元素 array2[i] = array[i]; } } }
一维数组的反转
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,2,5,10,9}; } static int[] reverse1(int[] array){ // 遍历一半长度进行元素交换 for (int i = 0; i < array.length / 2; i++) { int temp = array[i]; array[i] = array[array.length - 1 - i]; array[array.length - 1 - i] = temp; } return array; } static int[] reverse2(int[] array){ // 头尾双向交换 for ( int i = 0,j = array.length -1; i < j ; i++,j--) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } }
一维数组的线性查找 和 二分查找
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,2,5,10,9}; } // 线性查找 static int linearSearch(int[] array,int target){ for (int i = 0; i < array.length; i++) { if (target == array[i]) return i; // 找到直接返回索引 } return -1; // 找不到 返回-1 } // 二分查找 static int binarySearch(int[] array,int target){ int start = 0; int end = array.length -1; while ( start <= end ){ int mid = (start + end) / 2; // 每次二分都在不断变化的中轴游标 if (target == array[mid]) return mid; // 碰上了正好直接返回 else if (target > array[mid]) start = mid + 1; // 目标位置大于中轴,起始位置前推 else end = mid + 1; // 反之后退 } return -1; } }
【排序算法】
衡量排序算法的指标
- 时间复杂度 需要比较的次数和记录的移动次数
- 空间复杂度 内存耗费
- 稳定性 是否需要改变数据
按内外状态划分
- 内部排序 不需要外界辅助实现算法
- 外部排序 算法需要多部份完成,依赖外界辅助实现
【算法的特征】
- 对输入的描述和定义必须正确
- 输出必须要有结果产生
- 有穷性,在完成计算实现之后必须停止
- 确定性,算法的每一步都是明确的,不会歧义
- 可行性,算法的每一步都是清晰的,纸笔也能实现答案获取
冒泡排序
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,2,5,10,9}; } // 冒泡排序 static int[] bubbleSort(int[] array){ for (int i = 0; i < array.length -1; i++) { for (int j = 0; j < array.length -1; j++) { if (array[j] > array[j + i]){ int temp = array[i]; array[j] = array[j + 1]; array[j + 1] = temp; } } } return array; } }
快速排序 递归
https://blog.csdn.net/shujuelin/article/details/82423852
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,2,5,10,9}; } // 快速排序 static void quickSort(int[] arr,int start,int end){ int i,j,temp,t; if(start > end) return; i = start; j = end; //temp就是基准位 temp = arr[start]; while (i < j) { //先看右边,依次往左递减 while (temp <= arr[j] && i<j) j--; //再看左边,依次往右递增 while (temp>=arr[i]&&i<j) i++; //如果满足条件则交换 if (i<j) { t = arr[j]; arr[j] = arr[i]; arr[i] = t; } } //最后将基准为与i和j相等位置的数字交换 arr[start] = arr[i]; arr[i] = temp; //递归调用左半数组 quickSort(arr, start, j-1); //递归调用右半数组 quickSort(arr, j+1, end); } }
Arrays工具类
直接看源码,这里有非常多的重载
右边可以看到所有基本类型的重载方法
Arrays.sort() 将参数数组按顺序方式排序
关于parallelSort并行排序的资料:
https://www.infoq.cn/article/Java-8-Quiet-Features/
二分的重载
判断两个数组是否相同
fill 填充数组 你可以设置填充范围,不过默认全填充
复制数组直接照搬系统的复制方法...
将数组转换成String字符串形式
越界异常
package cn.dai; public class Arrays { public static void main(String[] args) { int[] array = {1,2,5,10,9}; // 越界异常 访问超过索引个数的位置 System.out.println(array[11]); } } Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at cn.dai.Arrays.main(Arrays.java:10) Process finished with exit code 1