目录
1.数组的定义与基本要素
1.1 为什么需要数组
我们前面学习了变量,知道变量是用来存储临时数据的,但是当我们需要存储很多的临时数据的时候怎么办呢,例如存储一个班的成绩表,我们当然可以给每个人都定义一个变量,但如果是一个学校的成绩呢,几个学校一起呢,这光是定义变量就已经让代码冗长的不行了,更别说后面的操作了。这样的场景就需要我们去使用数组了
1.2 数组定义
数组是一个变量,是一种数据的容器,存储相同数据类型的一组数据
注意:声明一个变量就是在内存空间划出一块合适的空间
声明一个数组就是在内存空间划出一串连续的空间
1.3 数组基本要素
标识符:数组的名称,用于区分不同的数组
数组元素:向数组中存放的数据
元素下标:对数组元素进行编号,从0开始,数组中的每个元素都可以通过下标来访问
元素类型:数组元素的数据类型
注意:数组长度固定不变,避免数组越界
1.4 数组特点
(1)这种容器是有一个限制规定: 在一个数组中保存的所有元素的数据类型都必须是同种类型的! 比如一个整数类型的数组[11,34,21,55]
(2)数组都有一个共同的属性:数组长度,在java程序中用length这个关键字来获取数组的长度值。
(3)数组中可以有很多个元素,这些元素是有排序位置的:这个位置序号,我们叫索引,而且这个索引是从0开始的,最后一个是arr.length-1。
2.数组的语法结构
(1)第一种定义方式, 定义的同时给赋了初始值, 也是第一种赋值方式:
int[] arr = {1,2,3,4,5,6,7,8,9,10};
其实这是一种连写,本质是是两个步骤:
第一步: int[] arr; //定义或叫声明一个 整数类型的数组变量 arr
第二步:arr = {1,2,3,4,5,6,7,8,9,10}; // 给整数类型的数组变量 arr 赋值, 注意可以这样理解,但是没这种赋值的语法
(2)第二种定义方式, 和第一种本质一样,只是写法不一样:
int[] arr = new int[]{20,30,40}; // 可以理解第一种写法是这种写法的简化,省略new int[]关键字
(3)第三种定义方式, 定义就只是定义, 没给赋初始值:
int[] arr = new int[3]; // 定义数组变量的时候没赋值,必须要指定数组的长度
3.Arrays工具类的使用
Arrays描述:Arrays是一个别人已经写好了可以让我们直接拿来用的工具类,我们只需将java.util.Arrays包导进我们的代码就可以使用里面的方法,使我们不用去写一些基础操作,例如排序,查找。
- java.util.Arrays
- sort()升序查询
- Arrays实战:
循环录入5位学员成绩,进行升序排序后输出结果
int[] scores = new int[5]; //成绩数组
Scanner input = new Scanner(System.in);
System.out.println("请输入5位学员的成绩:");
for(int i = 0; i < scores.length; i++){
scores[i] = input.nextInt();
}
Arrays.sort(scores);
System.out.print("学员成绩按升序排列:");
for(int i = 0; i < scores.length; i++){
System.out.print(scores[i] + " ");
}
4.数组的应用
4.1 求最大值和最小值
public class Demo03 {
public static void main(String[] args) {
//用程序找到最大值和最小值
int arr[] = {32,53,2,5,7,2,4,242,5,2,3,1,564};
int max = arr[0];
int min = arr[0];
for (int i = 0;i < arr.length;i++){
max = max<arr[i]?arr[i]:max;
min = min>arr[i]?arr[i]:min;
}
System.out.println("最大值:"+max);
System.out.println("最小值:"+min);
}
}
4.2 冒泡排序
冒泡排序是比较相邻两数的大小来完成排序的。
以升序排序为例,每趟排序完成之后,比较边界中的最大值就沉入底部,比较边界就向前移动一个位置。所以,第二趟排序开始时,比较边界是[0,n-2]。对于长度为n的序列,最多需要n趟完成排序,所以冒泡排序就由两层循环构成,最外层循环用于控制排序的趟数,最内层循环用于比较相邻数字的大小并在本趟排序完成时更新比较边界。
//冒泡排序
public static void bubbleSort(int[] arr){
int temp=0,len=arr.length;
int compareRange=len-1;//冒泡排序中,参与比较的数字的边界。
//冒泡排序主要是比较相邻两个数字的大小,以升序排列为例,如果前侧数字大于后侧数字,就进行交换,一直到比较边界。
for (int i = 0; i <len ; i++) {//n个数使用冒泡排序,最多需要n趟完成排序。最外层循环用于控制排序趟数
for (int j = 1; j <=compareRange ; j++) {
if(arr[j-1]>arr[j]){
temp=arr[j-1];
arr[j-1]=arr[j];
arr[j]=temp;
}
}
compareRange--;//每进行一趟排序,序列中最大数字就沉到底部,比较边界就向前移动一个位置。
}
System.out.println("排序后数组"+ Arrays.toString(arr));
}
在排序后期可能数组已经有序了而算法却还在一趟趟的比较数组元素大小,可以引入一个标记,如果在一趟排序中,数组元素没有发生过交换说明数组已经有序,跳出循环即可。优化后的代码如下:
//优化后的冒泡排序
public static void bubbleSort2(int[] arr){
int temp=0,len=arr.length;
int compareRange=len-1;//冒泡排序中,参与比较的数字的边界。
boolean flag=true;//标记排序时候已经提前完成
int compareCounter=0;
//冒泡排序主要是比较相邻两个数字的大小,以升序排列为例,如果前侧数字大于后侧数字,就进行交换,一直到比较边界。
while(flag) {
flag=false;
for (int j = 1; j <=compareRange ; j++) {
if(arr[j-1]>arr[j]){
temp=arr[j-1];
arr[j-1]=arr[j];
arr[j]=temp;
flag=true;
}
}
compareCounter++;
compareRange--;//每进行一趟排序,序列中最大数字就沉到底部,比较边界就向前移动一个位置。
}
System.out.println("优化后排序次数:"+(compareCounter-1));
System.out.println("排序后数组"+Arrays.toString(arr));
}
还可以利用这种标记的方法还可以检测数组是否有序,遍历一个数组比较其大小,对于满足要求的元素进行交换,如果不会发生交换则数组就是有序的,否则是无序的。
4.3 选择排序
算法描述:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换;
接着对不包括第一个记录以外的其他记录进行第二轮比较,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。
public class SelectionSort {
public static void selectionSort(int[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
int k = i;
// 找出最小值的下标
for (int j = i + 1; j < n; j++) {
k = a[k] < a[j] ? k : j;
}
// 将真正最小值和假设的最小值交换
if (k > i) {
int tmp = a[i];
a[i] = a[k];
a[k] = tmp;
}
}
}
5.二维数组
5.1 二维数组创建
语法:
- int[][] scores = new int[5][50];
- int scores[][] = new int [5][50];
定义:二维数组其实就是每个元素为一个一维数组
细节描述:
- [5][50]表示二维数组里包含了5个一维数组,每个一维数组里又包含了50个元素
- [5][]表示二维数组里包含了5个一维数组,每个一维数组长度不指定
5.2 二维数组实战
有5个班各5名学生某门课的成绩,计算5个班各自的总成绩
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int [][] array = new int[5][5]; //5个班的成绩
//i:班级 j:各班级的学生
for(int i=0;i<array.length;i++){
System.out.println("**********第"+(i+1)+"个班**********");
for(int j=0;j<array[i].length;j++){
System.out.print("请输入第"+(j+1)+"个学生的成绩:");
array[i][j]=input.nextInt();
}
}
System.out.println("***********成绩统计************");
int total; //保存总成绩
for(int i = 0; i < array.length; i++) {
String str = (i+1) + "班";
total = 0; //每次循环到此都将其归0
for(int j = 0; j < array[i].length; j++) {
total += array[i][j]; //成绩叠加
}
System.out.println(str+"总成绩:" + total);
}
}