零基础学java(4)——数组

一.数组的相关概念

/*
数组(array):
	简单的说,就是一组数
	
	当一组数据的数据类型,意义是一样的时候,那么为了方便的统一的管理它们,我们需要
	用新的数据的存储结构来进行存储。例如:数组
	
所谓数组(Array),就是相同数据类型的元素按一定顺序排列的集合,
就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,
然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。
组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。	

int[] scores = new int[7];
scores[0] = 89;
数组名:例如:scores
下标:范围:[0,长度-1]
	例如:[0]
元素:数组名[下标]
	例如:scores[0]

数组的长度:元素的总个数,可以这么表示:   数组名.length
*/
class Test01_Array{
    
    
	public static void main(String[] args){
    
    
		/*
		要存储本组学员的成绩,例如:第1组,有7个同学
		*/
		/*
		int score1 = 89;
		int score2 = 89;
		int score3 = 67;
		int score4 = 99;
		int score5 = 89;
		int score6 = 34;
		int score7 = 89;
		
		//用7个变量存储没问题,但是如果涉及到对数据的管理:例如,求最值,排序等,就非常麻烦
		*/
		int[] scores = new int[7];//用scores这一个统一的名称,来管理7个int类型的元素
		scores[0] = 89;//每一个元素都有自己的下标,编号,索引
		scores[1] = 89;
		scores[2] = 67;
		scores[3] = 99;
		scores[4] = 89;
		scores[5] = 34;
		scores[6] = 89;
	//	scores[7] = 56;// java.lang.ArrayIndexOutOfBoundsException:数组下标越界异常
		
		System.out.println(scores.length);
	}
}

二.数组声明,静态初始化,遍历(1)

/*
原则:先声明后使用

1、声明一个数组?
语法格式;
	元素的数据类型[] 数组名;
	例如:
	存储几个学员的成绩:int[] scores;
	存储几个学员的体重:double[] weights;
	存储几个学员的姓名:String[] names;

2、	数组的初始化?
需要完成两件事:
(1)确定数组的长度
(2)确定数组的元素的值

方式一:静态初始化
	数组名 = new 元素的数据类型[]{元素的值列表};
	
说明:如果数组的声明与静态初始化合成一句时
	元素的数据类型[] 数组名 = new 元素的数据类型[]{元素的值列表};
	甚至还可以简化:当且仅当,声明与静态初始化在一句时,才能这么简化
	元素的数据类型[] 数组名 = {元素的值列表};
方式二:动态初始化

3、如何表示一个数组的元素
数组名[下标]
下标的范围:[0,长度-1]

4、如何表示数组的长度
数组名.length

5、遍历/访问数组中的元素
for(int i=0; i<数组名.length; i++){
	Ssytem.out.println(数组名[i]);
}

回忆:
变量的声明与使用
(1)变量的声明
数据类型  变量名;
(2)变量的初始化
变量名 = 变量值;

声明和初始化合成一句
数据类型  变量名 = 变量初始值;
*/
class Test02_ArrayDefineAndUse{
    
    
	public static void main(String[] args){
    
    
		//(1)声明一个数组,用来存储几个学员的成绩
		int[] scores;
		
		//(2)初始化数组
		//静态初始化
		//数组名 = new 元素的数据类型[]{元素的值列表};
		scores = new int[]{
    
    89,45,67,88,90};
		
		//如果把数组的声明与静态初始化合成一句
		//int[] scores = new int[]{89,45,67,88,90};
		//甚至还可以简化:
		//int[] scores = {89,45,67,88,90};
		
		System.out.println("数组的长度:" + scores.length);
		
		//(3)遍历数组
		//下标index的范围:[0,长度-1]
		//下标index的范围:[0,scores.length-1]
		for(int index = 0; index<scores.length; index++){
    
    
			//每一个元素,就是数组名[下标]
			System.out.println(scores[index]);
		}
	}
}

三.练习一

练习一:用一个数组,随意保存5个奇数,并遍历显示

/*
1、数组的练习1:
	用一个数组,随意保存5个奇数,并且遍历显示
*/
class Test03_Exer1{
    
    
	public static void main(String[] args){
    
    
		//用一个数组,随意保存5个奇数,
		int[] array = {
    
    1,3,5,7,9};
		//遍历显示
		for(int i=0; i<array.length; i++){
    
    
			System.out.println(array[i]);
		}
	}
}

练习二:
用一个数组,保存平年1-12月的满月天数,并且遍历显示结果。

/*
2、数组的练习2:
	用一个数组,保存平年1-12月的满月天数,并且遍历显示结果:
	1月:31天
	2月:28天
	...
*/
class Test04_Exer2{
    
    
	public static void main(String[] args){
    
    
		//用一个数组,保存平年1-12月的满月天数,
		int[] daysOfMonth = {
    
    31,28,31,30,31,30,31,31,30,31,30,31};
		
		//并且遍历显示结果
		for(int i=0; i<daysOfMonth.length; i++){
    
    
			System.out.println((i+1) + "月:" + daysOfMonth[i]);
		}
	}
}	

练习3

用一个数组,保存星期一到星期天的7个英语单词,
从键盘输入1-7,显示对应的单词
/*
3、数组的练习3:
	用一个数组,保存星期一到星期天的7个英语单词,
	从键盘输入1-7,显示对应的单词
*/	
class Test05_Exer3{
    
    
	public static void main(String[] args){
    
    
		//用一个数组,保存星期一到星期天的7个英语单词,
		String[] weeks = {
    
    "Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
		
		//	从键盘输入1-7,显示对应的单词
		java.util.Scanner input = new java.util.Scanner(System.in);
		System.out.print("请输入星期(1-7):");
		int week = input.nextInt();
		
		if(week<1 || week>7){
    
    
			System.out.println("输入有误!");
		}else{
    
    
			//week对应的英语单词在weeks数组中
			//week=1,weeks[0]
			//week=2,weeks[1]
			//...
			System.out.println(week+"对应的星期的单词是:" + weeks[week-1]);
		}
		
	}
}

四.数组的内存分析(1)

/*
数组的存储:
1、数组下标为什么从0开始?
	下标表示的是这个元素的位置距离首地址的偏移量
2、数组名中存储的是什么
	数组名中存储的是数组在堆中一整块区域的首地址
3、数组的元素如何存储
	在堆中,依次连续的存储的

说明:
数组名,其实也是变量。

回忆:
变量的声明和初始化
	数据类型  变量名 = 变量值;
现在:
	int[] array = {1,3,5,7,9};
	其中的 int[]也是一种数据类型,数组类型,它是一种引用数据类型
	
	引用,表示引用一个“对象”,引用堆中的一块内存
	Java程序是在JVM中运行,JVM中的内存最最主要的两块区域:栈和堆
	其中的栈就是存储我们的局部变量(现在见到的变量都是局部变量),
		堆中存储的是对象
*/
class Test06_ArraySaveInMemory{
    
    
	public static void main(String[] args){
    
    
		int[] array = new int[]{
    
    1,3,5,7,9};
		//int[] array = {1,3,5,7,9};
		
		System.out.println(array);//打印数组名
		//结果:[I@15db9742
		//这个值是,数组对象的类型@对象的hashCode编码值
		//其中[I,表示int[]类型
		//15db9742是这个数组对象的hashCode编码值,类似于每个人都有一个身份证号
	}
}

五.数组的声明,动态初始化,遍历(2)

/*
数组的定义和初始化、使用的方式二:
1、数组的声明?不变
	元素的数据类型[] 数组名;

2、数组的初始化
(1)确定数组的长度
(2)确定数组的元素的值

方式一:静态初始化
	数组名 = new 元素的数据类型[]{元素的值列表};
	
	说明:(1)数组的长度由{}中的值的个数决定。
		(2)元素的值,在{}中直接指定
	
方式二:动态初始化
	数组名 = new 元素的数据类型[长度];
	说明:(1)数组的长度在[]指定 
		  (2)如果没有手动赋值之前,数组的元素有默认值
		  元素是基本数据类型:
		  byte,short,int,long:0
		  float,double:0.0
		  char:\u0000 字符编码为0的空字符
		  boolean:false
		  元素是引用数据类型:null
		  (3)给元素手动赋值
		  如果没有什么规律,就一个一个赋值;
		  如果有规律,可以使用循环赋值;

3、如何表示数组的长度?
数组名.length

4、如何表示一个数组的元素
数组名[下标]
下标的范围:[0,长度-1]

5、遍历数组
for(int i=0; i<数组的长度; i++){
	System.out.println(数组名[i]);
}	
*/
class Test07_ArrayDefineAndUse2{
    
    
	public static void main(String[] args){
    
    
		//例如:声明一个数组,用来存储26个大写的英文字母
		//(1)声明数组
		//char[] letters;
		
		//(2)动态初始化
		//数组名 = new 元素的数据类型[长度];
		//①确定数组的长度
		//letters = new char[26];
		
		//可以把声明与确定数组的长度合成一句
		char[] letters = new char[26];
		
		//(3)遍历数组的元素
		for(int i=0; i<letters.length; i++){
    
    
			System.out.println((int)letters[i]);//发现默认值是\u0000
		}
		
		//②确定数组的元素的值
		//letters[0] = 'A';
		//letters[1] = 'B';
		//...
		for(int i=0; i<letters.length; i++){
    
    
			//数组的元素 = 值;
			letters[i] = (char)('A' + i);
		}
		
		System.out.println("-------------------------------");
		//(4)遍历数组的元素
		for(int i=0; i<letters.length; i++){
    
    
			System.out.println(letters[i]);//发现默认值是\u0000
		}
	}
}

六.练习二

/*
1、数组的练习
用一个数组存储本组学员的成绩,并遍历显示
(1)其中学员的人数从键盘输入
(2)学员的成绩从键盘输入
*/
class Test08_Exer4{
    
    
	public static void main(String[] args){
    
    
		/*
		步骤:
		1、先确定人数,从键盘输入
		2、声明并创建数组,用来存储成绩
		3、确定每一个成绩:为每一个元素赋值
		4、遍历显示
		*/
		
		//1、先确定人数,从键盘输入
		java.util.Scanner input = new java.util.Scanner(System.in);
		System.out.print("请输入本组的人数:");
		int count = input.nextInt();
		
		//2、声明并创建数组,用来存储成绩
		//int[] scores = new int[长度];
		int[] scores = new int[count];
		
		//3、确定每一个成绩:为每一个元素赋值
		for(int i=0; i<count; i++){
    
    
			System.out.print("请输入第"+ (i+1) + "个学员的成绩:");
			//为元素赋值:为谁赋值,就把谁写在=的左边
			scores[i] = input.nextInt();//用键盘输入的值为元素赋值
		}
		
		//4、遍历显示
		System.out.println("本组学员的成绩如下:");
		for(int i=0; i<scores.length; i++){
    
    
			System.out.print(scores[i]+"\t");
		}
	}
}
/*
2、数组的练习
用一个数组存储26个英文字母的小写形式,
并遍历显示
'a'->'A’
*/
class Test09_Exer5{
    
    
	public static void main(String[] args){
    
    
		//用一个数组存储26个英文字母的小写形式
		//(1)声明并创建数组
		char[] letters = new char[26];
		
		//(2)为元素赋值,即把'a','b'等存储到letters数组中
		//因为有规律,所以用循环赋值
		for(int i=0; i<letters.length; i++){
    
    
			letters[i] = (char)('a' + i);
		}
		
		//(3)显示结果
		//'a'->'A’
		//->左边就是元素的值,右边是根据元素的值,算出来的
		//'a'的编码值是97,'A'编码值为65,差32
		//'b'的编码值是98,'B'编码值为66,差32
		for(int i=0; i<letters.length; i++){
    
    
			System.out.println(letters[i] +"->" + (char)(letters[i]-32));
		}
	}
}

七.数组中相关算法操作

1.在数组中找最大值/最小值

/*
在数组中找最大值/最小值
*/
class FindMax{
    
    
	public static void main(String[] args){
    
    
		int[] array = {
    
    4,2,6,8,1};
		
		//在数组中找最大值
	
		//(1)先假设第一个元素最大
		int max = array[0];
		//(2)用max中的值,与后面的值比较,如果有比max的值还大,就修改max的值
		for(int i=1; i<array.length; i++){
    
    
			if(array[i] > max){
    
    
				max = array[i];
			}
		}
		
		System.out.println("arr数组中最大值是:" + max);
	}
}

2.在数组中找最值及其下标

方法一:


class FindMaxAndIndex{
    
    
	public static void main(String[] args){
    
    
		int[] array = {
    
    4,2,-7,8,1,9};
		
		//最小值及其下标
		//(1)假设第一个元素最小
		int min = array[0];
		int index = 0;
		
		//(2)用min与后面的元素一一比较
		for(int i=1; i<array.length; i++){
    
    
			if(array[i] < min){
    
    
				min = array[i];
				index = i;
			}
		}
		System.out.println("最小值是:" + min);
		System.out.println("最小值的下标是:" + index);
	}
}

方法二:


class FindMaxAndIndex{
    
    
	public static void main(String[] args){
    
    
		int[] array = {
    
    4,2,-7,8,1,-7};
		
		//找出最小值,及其下标,但是如果最小值有两个或多个
		/*
		(1)先找出最小值
		(2)找出所有最小值的下标
		*/
		//(1)先找出最小值
		int min = array[0];
		for(int i=1; i<array.length; i++){
    
    
			if(array[i] < min){
    
    
				min = array[i];
			}
		}
		System.out.println("最小值:" + min);
		
		//(2)找出所有最小值的下标
		System.out.println("最小值的下标有:");
		for(int i=0; i<array.length; i++){
    
    
			if(array[i] == min){
    
    
				System.out.print("[" + i + "]\t");
			}
		}
		
	}
}

3.数组的元素的累加及平均值


class SumAndAvg{
    
    
	public static void main(String[] args){
    
    
		/*
		有一组学员的成绩存储在数组中,统计总分和平均分
		*/
		int[] scores = {
    
    34,89,67,54100};
		
		//求总分
		int sum = 0;
		for(int i=0; i<scores.length; i++){
    
    
			sum += scores[i];
		}
		
		//求平均值
		double avg = (double)sum / scores.length;
		System.out.println("总分:" + sum);
		System.out.println("人数:" + scores.length);
		System.out.println("平均分:" + avg);
		
	}
}

4.数组的反转

/*
数组反转:方法一
*/
class Reverse{
    
    
	public static void main(String[] args){
    
    
		//有一个数组,存储26个字母
		//'A'~'Z'
		char[] letters = new char[26];
		for(int i=0; i<letters.length; i++){
    
    
			letters[i] = (char)('A' + i);
		}
		
		//需求:要反转整个数组
		//原来letters[0]中存储的是'A'-->现在letters[0]中存储的是'Z'
		//...
		//原来letters[25]中存储的是'Z'-->现在letters[25]中存储的是'A'
		//方式一:定义一个与原来的数组长度相同的新数组,并且逆序复制元素
		char[] newLetters = new char[letters.length];
		//逆序复制元素
		for(int i=0; i<newLetters.length; i++){
    
    
			newLetters[i] = letters[letters.length-1-i];
		}
		
		//让letters这个数组名指向新的数组
		letters = newLetters;
		
		//显示结果
		for(int i=0; i<letters.length; i++){
    
    
			System.out.println(letters[i]);
		}
	}
}
/*
数组反转:方法二
*/
class Test14_Reverse_2{
    
    
	public static void main(String[] args){
    
    
		//有一个数组,存储26个字母
		//'A'~'Z'
		char[] letters = new char[26];
		for(int i=0; i<letters.length; i++){
    
    
			letters[i] = (char)('A' + i);
		}
		
		//需求:要反转整个数组
		//原来letters[0]中存储的是'A'-->现在letters[0]中存储的是'Z'
		//...
		//原来letters[25]中存储的是'Z'-->现在letters[25]中存储的是'A'
		//方式二:首尾交换
		//问题1:交换几次   次数 = 长度/2  例如:6个元素交换3次,5个元素交换2次
		/*
		这个i可以用作下标,同时循环的次数,可以表示交换的次数
		*/
		for(int i=0; i<letters.length/2; i++){
    
    
			//问题2:谁和谁交换
			//letters[0] ~ letters[25]
			//letters[1] ~ letters[24]
			//..
			//首尾交换
			//letters[i] ~ letters[长度-1 - i]
			
			//问题3:如何交换
			//借助第三个变量
			char temp = letters[i];
			letters[i] = letters[letters.length-1-i];
			letters[letters.length-1-i] = temp;
		}
		
		//显示结果
		for(int i=0; i<letters.length; i++){
    
    
			System.out.println(letters[i]);
		}
	}
}

5.数组的复制

/*
方法一
*/
class Copy_01{
    
    
	public static void main(String[] args){
    
    
		//(1)复制一个和原来一样的数组,长度和元素
		int[] arr = {
    
    1,2,3,4,5};
		
		/*
		(1)创建一个新数组,和原来的数组一样
		*/
		int[] newArr = new int[arr.length];
		/*
		(2)复制元素
		*/
		for(int i=0; i<newArr.length; i++){
    
    
			newArr[i] = arr[i];
		}
		
		//(3)遍历新数组
		for(int i=0; i<newArr.length; i++){
    
    
			System.out.println(newArr[i]);
		}
	}
}
/*
方法二
*/
class Copy_01{
    
    
	public static void main(String[] args){
    
    
		//(1)复制一个和原来一样的数组,长度和元素
		int[] arr = {
    
    1,2,3,4,5};
		
		/*
		(1)创建一个新数组,和原来的数组一样
		*/
		int[] newArr = new int[arr.length];
		/*
		(2)复制元素
		*/
		for(int i=0; i<newArr.length; i++){
    
    
			newArr[i] = arr[i];
		}
		
		//(3)遍历新数组
		for(int i=0; i<newArr.length; i++){
    
    
			System.out.println(newArr[i]);
		}
	}
}
/*
方法三
*/
class Copy_03{
    
    
	public static void main(String[] args){
    
    
		//(3)复制一个比原来的长的
		int[] arr = {
    
    1,2,3,4,5};
		
		//需求:新增加了几个数据,需要存储,此时需要把数组进行扩容
		//(1)创建一个新数组,例如:新数组的长度为原来的2倍
		int[] newArr = new int[arr.length*2];
		
		//(2)复制元素
		for(int i=0; i<arr.length; i++){
    
    
			newArr[i] = arr[i];
		}
		
		//(3)遍历结果
		for(int i=0; i<newArr.length; i++){
    
    
			System.out.println(newArr[i]);
		}
	}
}
/*
方法四
*/
class Copy_04{
    
    
	public static void main(String[] args){
    
    
		int[] arr = {
    
    1,2,3,4,5};
		
		/*
		复制一个新数组,新数组的长度由键盘输入,可能和原来一样,可能比原来的短,可能比原来的长
		*/
		/*
		(1)从键盘输入新数组的长度
		*/
		java.util.Scanner input = new java.util.Scanner(System.in);
		System.out.print("请输入新数组的长度:");
		int len = input.nextInt();
		
		//(2)创建新数组
		int[] newArr = new int[len];
		
		//(3)复制元素,这里都是从原数组的[0]开始复制
		//i<arr.length && i<newArr.length保证newArr[i] = arr[i];左右两边都不越界
		for(int i=0; i<arr.length && i<newArr.length; i++){
    
    
			newArr[i] = arr[i];
		}
		
		//(4)遍历结果
		for(int i=0; i<newArr.length; i++){
    
    
			System.out.println(newArr[i]);
		}
	}
}

6.数组的查找

1.数组中的元素是无序的

数组中的元素是无序的:
顺序查找


class Test02_Find{
    
    
	public static void main(String[] args){
    
    
		int[] arr = {
    
    1,4,5,7,9};
		
		//在arr的数组中,查找2的下标,或者判断2在数组中是否存在
		int value = 2;
		int index = -1;//因为正常的下标,没有-1
		for(int i=0; i<arr.length; i++){
    
    
			if(arr[i] == value){
    
    
				index = i;
				break;
			}
		}
		if(index == -1){
    
    
			System.out.println(value+"不存在");
		}else{
    
    
			System.out.println(value+"在数组中的下标是:" + index);
		}
		
	}
}

2.数组重点元素是有序的

顺序查找和二分查找


class Find_2{
    
    
	public static void main(String[] args){
    
    
		int[] arr = {
    
    1,2,5,7,9,10};//有序的,从小到大
		
		int value = 10;
		
		int index = -1;
		int left = 0;
		int right = arr.length-1;
		int mid = (left + right)/2;
		/*
		假设数组的长度是5,left=0,right=4,mid = 2
		假设数组的长度是6,left=0,right=5,mid = 2
		*/
		
		while(left<=right){
    
    
			if(arr[mid] == value){
    
    //找到了
				index = mid;
				break;
			}else if(value > arr[mid]){
    
    //去右边找
				left = mid + 1;//因为mid比较过了,就不用看了,从mid的下一个作为左边界
			}else{
    
    //说明value < arr[mid] 去左边找
				right = mid - 1;
			}
			mid = (left + right)/2;//重新计算mid,因为left或right修改了
		}
		
		if(index == -1){
    
    
			System.out.println(value+"不存在");
		}else{
    
    
			System.out.println(value+"在数组中的下标是:" + index);
		}
	}
}

7.数组的排序

1.冒泡排序


class BubbleSort{
    
    
	public static void main(String[] args){
    
    
		int[] arr = {
    
    4,2,1,8,3};
		
		//希望数组最终是{1,2,3,4,8}或{8,4,3,2,1}
		//现在要实现从小到大
		/*
		冒泡排序:通过相邻元素比较,如果相邻元素的顺序不符合要求,那么就交换。
				 经过几轮之后,实现最终的排序。每一轮都会有一个已经到达正确位置的元素退出比较。
				 
		第一轮:
			第1次:arr[0]和arr[1]比较,4和2比较,不符合要求,交换,{2,4,1,8,3}
			第2次:arr[1]和arr[2]比较,4和1比较,不符合要求,交换,{2,1,4,8,3}
			第3次:arr[2]和arr[3]比较,4和8比较,符合要求
			第4次:arr[3]和arr[4]比较,8和3比较,不符合要求,交换,{2,1,4,3,8}
		
		第一轮之后,最大的,沉到底,跑到最右边
		
		第二轮:
			第1次:arr[0]和arr[1]比较,2和1比较,不符合要求,交换,{1,2,4,3,8}
			第2次:arr[1]和arr[2]比较,2和4比较,符合要求
			第3次:arr[2]和arr[3]比较,4和3比较,不符合要求,交换,{1,2,3,4,8}
		
		第二轮之后,次大的到达正确位置
		
		第三轮:
			第1次:arr[0]和arr[1]比较,1和2比较,符合要求
			第2次:arr[1]和arr[2]比较,2和3比较,符合要求
			
		第四轮:
			第1次:arr[0]和arr[1]比较,1和2比较,符合要求
			
		轮数 = 数组的长度 - 1; //因为每一轮只能确定一个
		*/
		//轮数
		for(int i=1; i<arr.length; i++){
    
    //循环次数 = 长度 -1,控制轮数
			/*
			例如:5个元素
			每一轮的次数 = 长度 - i;
			第1轮:4次
			第2轮:3次
			第3轮:2次
			第4轮:1次
			
			第1轮:arr[0]与arr[1]、arr[1]和arr[2]、arr[2]和arr[3]、arr[3]和arr[4]
			第2轮:arr[0]与arr[1]、arr[1]和arr[2]、arr[2]和arr[3]
			第3轮:arr[0]与arr[1]、arr[1]和arr[2]
			第4轮:arr[0]与arr[1]
			
			相邻元素:arr[j] 与 arr[j+1]
			第1轮:j的值 :0,1,2,3  j<4		j<5-1	j<5-i
			第2轮:j的值 :0,1,2	j<3		j<5-2
			第3轮:j的值 :0,1		j<2		j<5-3
			第4轮:j的值 :0		j<1		j<5-4
			*/
			for(int j=0; j<5-i; j++){
    
    
				if(arr[j] > arr[j+1]){
    
    //相邻元素比较,左>右,交换
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		
		//显示结果
		for(int i=0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
	}
}

2.直接选择排序


class SelectSort{
    
    
	public static void main(String[] args){
    
    
		int[] arr = {
    
    4,2,1,8,3};
		
		/*
		直接选择排序:
			经过很多轮
			每一轮,把当前“未排序”的元素中最大/最小的元素及其位置找出来,
			然后与这“最大/最小”值本来/正确的位置的元素进行交换
		也可以理解为直接插入排序
		
		以从小到大为例
		第一轮:
			找出本轮最小的值:1,它的下标[2]
			这个最小值,应该在[0]位置,就交换[2]和[0]位置的元素
			{1,2,4,8,3}
		第二轮:
			找出本轮未排序元素中最小的值:2,它的下标[1]
			这个最小值,应该在[1]位置,就可以不动
		第三轮:
			找出本轮未排序元素中最小的值:3,它的下标[4]
			这个最小值,应该在[2]位置,就交换[4]和[2]位置的元素
			{1,2,3,8,4}
		第四轮:
			找出本轮未排序元素中最小的值:4,它的下标[4]
			这个最小值,应该在[3]位置,就交换[4]和[3]位置的元素
			{1,2,3,4,8}
			
		轮数:长度-1
		*/
		for(int i=0; i<arr.length-1; i++){
    
    //总轮数 = 长度-1
			//(1)找出本轮未排序元素中的最小值及其下标
			/*
			第1轮:[0]~[4]范围内最小值及其下标
			第2轮:[1]~[4]范围内最小值及其下标
			第3轮:[2]~[4]范围内最小值及其下标
			第4轮:[3]~[4]范围内最小值及其下标
			
			思路:假设本轮未排序的第一个元素最小,然后用min与本轮后面的元素一一比较
			*/
			int min = arr[i];
			int index = i;
			for(int j = i+1; j<arr.length; j++){
    
    
				if(arr[j] < min){
    
    
					min = arr[j];
					index = j;
				}
			}
			
			//(2)看这个最小值是否在它应该在的位置
			/*
			第1轮:最小值应该在[0]
			第2轮:最小值应该在[1]
			第3轮:最小值应该在[2]
			第4轮:最小值应该在[3]
			*/
			if(index != i){
    
    //交换arr[i]和arr[index]
				int temp = arr[i];
				arr[i] = arr[index];
				arr[index] = temp;
			}
		}
		
		//显示结果
		for(int i=0; i<arr.length; i++){
    
    
			System.out.print(arr[i] + " ");
		}
	}
}

八.二维数组

1.静态初始化

/*
数组的维度:
	一维数组、二维数组、三维数组...

二维数组:
	有行有列的表格,二维表

1、如何声明一个二维数组?	
语法格式:
	元素的数据类型[][] 数组名;
	
2、如何初始化二维数组?
初始化:
(1)确定行数
(2)确定每一行的列数
(3)确定元素的值


回忆:
	一维数组初始化(1)确定长度,元素的个数(2)确定元素的值
	
(1)静态初始化
	二维数组名 = new 元素的数据类型[][]{
    
    {第一行的值列表},{第二行的值列表},...{第n行的值列表}};
(2)动态初始化	

3、如何表示二维数组的行数?
二维数组名.length

4、如何表示一行
此时把二维数组看成一个一维数组,把一行看成一个元素
一行:二维数组名[行下标]
行下标的范围:[0,二维数组总行数-1]

5、如何表示每一行的列数?即每一行元素的个数
二维数组的一行,其实又是一个一维数组
二维数组名[行下标].length

6、如何表示某行某列的一个元素呢?
二维数组名[行下标][列下标]

列下标的范围:[0, 该行的列数-1]

7、遍历二维数组
for(int i=0; i<行数; i++){
	for(int j=0; j<该行的列数; j++){
		System.out.print(二维数组名[i][j] + " ");
	}
	System.out.println();
}

for(int i=0; i<二维数组名.length; i++){
	for(int j=0; j<二维数组名[i].length; j++){
		System.out.print(二维数组名[i][j] + " ");
	}
	System.out.println();
}

*/
class Test05_ManyDimensionalArray{
    
    
	public static void main(String[] args){
    
    
		//存储多个组的学员的成绩,每一个组单独一行存储
		/*
		//1、声明一个二维数组
		int[][] scores;
		
		//2、静态初始化
		scores = new int[][]{
			{67,89,45},
			{90,99,88,100},
			{34,56,12,67}
		};
		*/
		//如果把声明和静态初始化一起完成,可以简化
		int[][] scores = {
    
    
			{
    
    67,89,45},
			{
    
    90,99,88,100},
			{
    
    34,56,12,67}
		};
		
		System.out.println("行数:" + scores.length);
		
		//3、遍历
		for(int i=0; i<scores.length; i++){
    
    //行数
			//scores[i]代表一行,看成一个整体
			for(int j=0; j<scores[i].length; j++){
    
    
				System.out.print(scores[i][j]+" ");
			}
			System.out.println();
		}
	}
}

2.练习

  • 练习一:
/*
 1
 2 2
 3 3 3
 4 4 4 4
 5 5 5 5 5
*/
class Test06_Exer1{
    
    
	public static void main(String[] args){
    
    
		int[][] arr = {
    
    {
    
    1},{
    
    2,2},{
    
    3,3,3},{
    
    4,4,4,4},{
    
    5,5,5,5,5}};
		
		//遍历二维数组的arr.length行的数据
		for(int i=0; i<arr.length; i++){
    
    
			//每一行
			//(1)先打印arr[i]行的几个元素
			for(int j=0; j<arr[i].length; j++){
    
    
				System.out.print(arr[i][j] + " ");
			}
			//(2)换行
			System.out.println();
		}
	}
} 
  • 练习二:
/*
 1 1 1 1 1
 2 2 2 2 2
 3 3 3 3 3
 4 4 4 4 4
 */

class Test07_Exer2{
    
    
	public static void main(String[] args){
    
    
		int[][] arr = {
    
    
			{
    
    1,1,1,1,1},
			{
    
    2,2,2,2,2},
			{
    
    3,3,3,3,3},
			{
    
    4,4,4,4,4}
		};
		
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
	}
}

3.内存分析

在这里插入图片描述

/*
看内存图
*/
class Test08_Save{
    
    
	public static void main(String[] args){
    
    
		int[][] arr = {
    
    
			{
    
    1,1,1,1,1},
			{
    
    2,2,2,2,2},
			{
    
    3,3,3,3,3},
			{
    
    4,4,4,4,4}
		};
		
		System.out.println(arr[0]);//下标为0的行
		//[I@15db9742
		//对象数据类型@hash码
		//[I :代表元素是int类型的一维数组
		
		int[] array = {
    
    1,1,1,1,1};
		System.out.println(array);
		//[I@6d06d69c
	}
}

4.动态初始化及其内存

/*
二维数组的初始化:
1、静态初始化

2、动态初始化
(1)确定总行数
(2)确定每一行的列数
(3)确定元素的值

 1 1 1 1 1
 2 2 2 2 2
 3 3 3 3 3
 4 4 4 4 4

*/
class Test09_ManyDimensionalArray{
    
    
	public static void main(String[] args){
    
    
		//1、声明一个二维数组
		//int[][] arr;
		
		//2、动态初始化
		//(1)确定总行数
		//arr = new int[4][];
		
		//如果声明和确定总行数合起来
		int[][] arr = new int[4][];
		
		System.out.println("总行数:" + arr.length);
		//System.out.println("arr[0]行:" + arr[0]);//null,因为此时该行的更详细的信息没有
		
		//(2)确定每一行的列数
		//因为arr[0]是代表一行,代表一个一维数组
		//arr[0] = new int[5];
		//System.out.println(arr[0][2]);
		
		//(3)确定元素的值
		//arr[0][0] = 1;
		//arr[0][1] = 1;
		//arr[0][2] = 1;
		//arr[0][3] = 1;
		//arr[0][4] = 1;
		
		//(2)确定每一行的列数
		for(int i=0; i<arr.length; i++){
    
    
			arr[i] = new int[5];//每一行都是5个元素
		}
		
		//(3)确定元素的值
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				arr[i][j] = i+1;
			}
		}
		
		//(4)遍历
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
	}
}
/*
 1 1 1 1 1
 2 2 2 2 2
 3 3 3 3 3
 4 4 4 4 4
 */
 
class Test10_ManyDimensionalArray{
    
    
	public static void main(String[] args){
    
    
		//当二维数组每一行的列数是相同的
		
		//声明,确定行数,确定每一行的列数一起完成
		int[][] arr = new int[4][5];//共4行,每一行都是5列
		
		//(3)确定元素的值
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				arr[i][j] = i+1;
			}
		}
		
		//(4)遍历
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
	}
}

5.练习

/*
 1
 2 2
 3 3 3
 4 4 4 4
 5 5 5 5 5
*/
 
class Test11_Exer1{
    
    
	public static void main(String[] args){
    
    
		//1、声明一个二维数组,并且确定行数
		//因为每一行的列数不同,这里无法直接确定列数
		int[][]  arr = new int[5][];
		
		//2、确定每一行的列数
		for(int i=0; i<arr.length; i++){
    
    
			/*
			arr[0] 的列数是1
			arr[1] 的列数是2
			arr[2] 的列数是3
			arr[3] 的列数是4
			arr[4] 的列数是5
			*/
			arr[i] = new int[i+1];
		}
		
		//3、确定元素的值
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				arr[i][j] = i+1;
			}
		}
		
		//4、遍历显示
		for(int i=0; i<arr.length; i++){
    
    
			for(int j=0; j<arr[i].length; j++){
    
    
				System.out.print(arr[i][j] + " ");
			}
			System.out.println();
		}
		
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43912367/article/details/117060963
今日推荐