java学习笔记-第六章:数组排序查找

总体内容

数组:array
在这里插入图片描述

数组

数组的介绍

  1. 数组是引用数据类型
  2. 数组用于存储一组同一类型的数据
    在这里插入图片描述
  3. 数组的一个入门例子
    3.1 定义一个数组:
    在这里插入图片描述
    3.2 获取数组中的数据
    在这里插入图片描述
    3.3 遍历整个数组,累计数组中的值
    用3.4进行改进
    在这里插入图片描述
    3.4 获取数组的长度:数组.length
    在这里插入图片描述

数组的具体使用

数组的定义和引用

  1. 数组定义的三种方法(1种静态,2种动态)
    1.1 数据类型[] a = {元素值…}–>适用于元素个数有限(静态初始化–>元素值已经确定
    在这里插入图片描述
    1.2 先声明后分配空间(动态初始化–>可以动态赋值
    int[] a; //声明
    a = new int[3]; //分配空间

    1.3 声明和分配空间同时进行(动态初始化–>可以动态赋值)
    数据类型[] 数组名 = new 数据类型[大小] 等价为
    数据类型 数组名[] = new 数据类型[大小]
    int[] a = new int[3];
  2. 引用:数组名[下标]
    2.1 数组的下标从0开始
  3. 循环输入5个数到double数组中,循环输出该数组
    3.1 循环输入
    在这里插入图片描述
    3.2 循环输出
    在这里插入图片描述

数组的细节

  1. 数组是多个相同类型数据的组合,或者数据间可以进行自动转换
    在这里插入图片描述
  2. 数据中的数据类型可以是基本数据类型和引用数据类型,但不能混用
  3. 使用数组的步骤:①声明并开辟空间②赋值③使用
  4. 数组创建后,如果没有赋值,有默认值
    3.1 整数类型:(byte,short,int,long)–>0
    3.2 浮点数类型:(float,double)0.0
    3.3 字符类型:(char)\u0000
    3.4 布尔类型:(boolean)false
    3.5 字符串类型:(String) null
  5. 数组的下标必须在指定范围内使用,不然会报下标越界(长度-1)–>运行时会报错
  6. 数组是引用数据类型,数组型数据是对象(Object)

数组练习

练习1:字符数组存入A-Z(唯一注意:要强制类型转换)

'A’+1的返回值int类型,要强制转换为char类型
在这里插入图片描述

※练习2:求数组中的最大值,以及对应下标
  1. 思路:
    1.1 假定数组第一个值是最大值,max=arr[0],maxIndex=0
    1.2 从下标1开始遍历数组,如果max<当前元素,就max=当前元素,maxIndex=当前下标
  2. 代码
    在这里插入图片描述

数组的赋值机制(内存布局)

  1. 基本类型的赋值和引用类型的赋值不同
    1.1. 基本类型是传值赋的值只是数值)–>值拷贝/传递
    1.2 引用类型是传址赋的值是地址)–>引用传递
  2. 基本类型指向值,引用类型指向地址(用内存解释)
    在这里插入图片描述

数组拷贝(内容一致,地址独立)

在这里插入图片描述
在这里插入图片描述
使用new来开辟新空间
在这里插入图片描述

数组反转

1. 方法一:找规律交换

1.1重点是思路(找规律):
在这里插入图片描述
1.2. 代码(循环的次数,交换的两值以及如何交换)(缺少一个遍历,不写了)
在这里插入图片描述

2. 方法二:逆序赋值法(逆序拷贝+指向同一地址)

for循环定义了两个变量(一个向前一个向后)
在这里插入图片描述

数组扩容和缩减(动态添加或缩减元素)

数组扩容(对数组拷贝的应用)

  1. 数组扩容要求
    1.1 动态给数组添加元素(数组扩容)
    1.2 静态数组,添加的元素4放在数组最后
    1.3 是否继续添加
    在这里插入图片描述
  2. 思路:
    2.1 大致就是arr数组拷贝->arrNew,但是长度是arr.length+1,前arr.length是arr原本的元素,最后一个是扩容的元素
    2.2 定义一个新数组arrNew[],int[] arrNew = new int[arr.length+1]
    2.3 遍历整个数组,依次将arr的元素拷贝到arrNew数组中
    2.4 将4赋给arrNew[arrNew.length-1](最后一个元素)
    2.5 让arr指向arrNew,原来的arr被销毁
    在这里插入图片描述
    2.6 最后一个动态添加的效果,使用do-while循环
    注意:变量的作用域:
    ①在do循环体内定义的变量,在while中是不能使用的!!!
    ②全局变量在循环体内可以改变其值
    ③charAt(0),从字符串中取第一个字符
		char key = 'n';
	    int[] arr = {1,2,3};
		do{
			int[] arrNew = new int[arr.length+1];
			for(int i = 0;i < arr.length;i++){
				arrNew[i] = arr[i];
			}
			System.out.println("请输入添加的数");
			int num = scanner.nextInt();
			arrNew[arrNew.length-1] = num;
			arr = arrNew;
			System.out.println("扩容后数组为:");
			for(int i = 0;i < arr.length;i++){
				System.out.print(arr[i]+"\t");
			}
			System.out.println("是否继续添加?y/n");
			//第一种:在循环外定义变量,用while做出判断,跳出循环
			key = scanner.next().charAt(0);
			//第二种:在循环内定义变量,在循环内用if做判断,break跳出循环
			//int key = scanner.next().charAt(0);
			// if(key == 'n'){
			// 	break;
			// }
		}while(key != 'n');

数组缩减

  1. 要求:
    1.1 每次缩减数组最后一个元素
    1.2 提示是否继续缩减?y/n
    1.3 当数组中剩一个元素时,提示不能再缩减
  2. 思路
    2.1是扩容的逆,新创建的数组长度是原先数组-1,然后数组拷贝到新数组,原数组指向新数组
    2.2 解读要求3: 在数组拷贝完成后,对数组长度进行判断,如果长度=1,则使用break跳出循环
    2.3 如果数组长度>1则不跳出循环,询问是否继续缩减,当输入为n时跳出循环
    在这里插入图片描述

排序(主要介绍冒泡排序)

排序的介绍

在这里插入图片描述

冒泡排序

介绍

在这里插入图片描述

冒泡排序的案例

在这里插入图片描述

冒泡排序解析(从后向前)以及特点总结
  1. 第一轮排序
    1.1 第一次比较 24,69,80,13,57
    1.2 第二次比较 24,69,13,80,57
    1.3 第三次比较 24,13,69,80,57
    1.4 第四次比较 13,24,69,80,57 (此时最小的数已经冒出来了)
  2. 第二轮排序
    2.1 第一次比较 13,24,69,57,80
    2.2 第二次比较 13,24,57,69,80
    2.3 第三次比较 13,24,57,69,80 **
  3. 第三轮排序
    3.1 第一次比较 13,24,57,69,80
    3.2 第二次比较 13,24,57,69,80
  4. 第四轮排序
    4.1 第一次比较 13,24,57,69,80

特点总结:

  1. 本案例一共5个元素
  2. 一共进行了4次排序(外循环次数)
  3. 每一次排序里比较的次数在减少(内循环次数)
  4. 每一次排序都能确定一个数的位置
  5. 第一次排序,内层循环4次,i=arr.length-1,i>0,i–; i=4 j=arr.length-1,j=4,3,2,1
    i=3,j=4,3,2 arr.length-i
※冒泡排序代码实现(后到前和前到后)
  1. 从后到前的冒泡
    1.1外层循环–>几轮排序
    1.2 内层循环–>几次比较

    1.3每一次比较都从最后一个元素开始,所以int j = arr.length-1
    1.4 找规律得出j的临界
    1.5 注意:j和j-1进行比较(和前一个进行比较),不能是j和j+1比较,因为那样会越界
		int[] arr = {24,69,80,13,57};
		int temp = 0;
		//外层循环-->几轮排序
		for(int i = arr.length-1;i > 0;i--){
			//内层循环-->几次比较
			//每一次比较都从最后一个元素开始,所以int j = arr.length-1
			//找规律:i = 4时,j = 4,3,2,1
			//i = 3时,j = 4,3,2
			//以此类推发现:j最小的数 + i = 5 ,所以j的临界就是arr.length-i
			for(int j = arr.length-1;j >= arr.length-i;j--){
				//j和j-1进行比较,不能是j和j+1,那样会越界(和前一个进行比较)
				if(arr[j - 1] > arr[j]){
					temp = arr[j];
					arr[j] = arr[j - 1];
					arr[j - 1] = temp;
				}
			}
		}
		System.out.println("=====排序后=====");
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i]+"\t");
		}
  1. 老师讲的从前到后的冒泡
		int[] arr = {24,69,80,13,57};
		int temp = 0;
		for(int i = 0;i < arr.length - 1;i++){
			for(int j = 0;j < arr.length - 1 - i;j++){
				//和后一个进行比较
				if(arr[j + 1] < arr[j]){
					temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
		System.out.println("=====排序后=====");
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i]+"\t");
		}

查找(主要介绍顺序查找)

查找的介绍

在这里插入图片描述
二分查找:对有序数组进行查找,先让要查找的数和数组中间的数比较,若比中间数字大,则和数组右半边的中间的数进行比较,若比中间数字小,则和数组左半边的中间的数进行比较,依此类推

顺序查找案例

在这里插入图片描述

一个经典验证方法:
定义一个变量,判断查找有没有成功,如果成功,该变量值=下标,如果不成功,则保留该变量原先的数值

import java.util.Scanner;
public class HelloWorld {
    public static void main(String []args) {
		Scanner n = new Scanner(System.in);
		String[] arr = {"王胖子","高瘦子","高梦梦"};
		System.out.println("请输入一个名字");
		String findName = n.next();
		int index = -1;
		for(int i = 0;i < arr.length;i++){
			if(findName.equals(arr[i])){
				System.out.println("找到了"+findName+"下标为:"+i);
				index = i;
			}
		}
		if(index == -1){
			System.out.println("未找到"+findName);
		}
    }
}

多维数组-二维数组

二维数组介绍及快速入门案例

  1. 一维数组的每一个数组又是一个数组,称为二维数组
    在这里插入图片描述
  2. 二维数组的定义
    在这里插入图片描述
  3. 二维数组的遍历
    3.1 arr[i]:下标为i的一维数组
    3.2 arr.length:二维数组有多少个元素
    3.3 arr[i].length:下标为i的一维数组长度
    3.4 arr[i][j]:二维数组第(i+1)个一维数组的第(j+1)个的值
for(int i = 0;i < arr.length;i++){
	for(int j = 0;j < arr[i].length;j++){
		System.out.print(arr[i][j]+"\t");
	}
	//换行
	System.out.println();
}

二维数组的使用

动态初始化1(不写具体赋值)

1. 语法

数据类型 [][] 数组名 = new 数据类型[大小][大小]
1.1 第一个大小是一维数组的个数
1.2 第二个大小是一维数组中元素的个数

2. ※二维数组内存布局

二维数组在栈中指向堆中的一块地址,这个地址中保存了二维数组的两个元素(两个一维数组)的地址,这两个地址中保存了一维数组的元素
在这里插入图片描述

动态初始化2(不写具体赋值)

1. 语法

1.1 先声明:类型[][] 数组名;
1.2 再定义(开辟空间):数组名 = new 类型[大小][大小]
1.3 赋值(有默认值)
1.4 使用

2. 案例(※每个一维数组个数不一样)
  1. 先声明有3个一维数组,但是此时一维数组没有指向任何地址(没有开辟空间)
  2. 等到循环中,再为每一个一维数组开辟空间:arr[i]表示第几个一维数组,为一维数组开辟空间用到了new 类型[大小]arr[i]=new int[i+1]
    在这里插入图片描述

静态初始化(不写new)

  1. 每一个元素必须是一维数组!否则会报错,在这里100是一个int而不是数组。
    在这里插入图片描述
  2. 使用
    在这里插入图片描述

二维数组的细节

在这里插入图片描述

二维数组的案例–杨辉三角

  1. 要求
    在这里插入图片描述
  2. 规律(重点是第三条规律)
    在这里插入图片描述
  3. 代码

重点是:
如果是第一个和最后一个赋为1
如果是中间的(不是第一个和最后一个)就是arr[i - 1][j] + arr[i - 1][j - 1]

public class HelloWorld {
    public static void main(String []args) {
		int[][] arr = new int[10][];
		for(int i = 0;i < arr.length;i++){
			arr[i] = new int[i+1];
			for(int j =0;j < arr[i].length;j++){
				if(j == 0 || j == arr[i].length-1){
					arr[i][j] = 1;
				}else{
					//重点是这一句:给不是第一个和最后一个元素赋值
					arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
				}
			}
		}
		for(int i = 0;i < arr.length;i++){
			for(int j =0;j < arr[i].length;j++){
					System.out.print(arr[i][j]+"\t");
				}
			System.out.println();
		}
    }
}
  1. 运行结果
    在这里插入图片描述

小练习

在这里插入图片描述

本章案例练习

一. 定义语法练习(好好看)

在这里插入图片描述

二. ※升序数组插入一个值,该数组仍升序(2种方法)

在这里插入图片描述

  1. 方法1:扩容 + 冒泡排序
		Scanner scanner = new Scanner(System.in);
		int[] arr = {10,12,45,90};
		//数组扩容
		//创建一个新数组,将arr数组拷贝到新数组中
		//插入数字,并让arr指向新数组
		int[] newArr = new int[arr.length+1];
		System.out.println("请输入要插入的数字");
		int findName = scanner.nextInt();
		for(int i = 0;i < arr.length;i++){
			newArr[i] = arr[i];
		}
		newArr[newArr.length - 1] = findName;
		arr = newArr;
		//进行冒泡排序
		int temp = 0;
		for(int i = arr.length - 1;i > 0;i--){
			for(int j = arr.length - 1;j >= arr.length - i;j--){
				if(arr[j - 1] > arr[j]){
					System.out.println(arr[j-1]+"换成了"+arr[j]);
					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]+"\t");
		}
  1. ※方法2:顺序查找 + 数组扩容
    2.1 顺序查找,看添加的数要放在数组的哪个位置上(获取位置下标)
    2.2 再进行扩容
    在这里插入图片描述

顺序查找有两种情况

  1. 要插入的值比数组中的值都大,则插入到数组最后面(用一个index变量判断)
  2. 若数组中有比插入的值大的元素,那么插入值就插入到该元素的这个位置(index来接收下标值)

数组扩容

  1. 这里注意:通常的扩容在拷贝元素时,只定义一个变量i,使得旧数组的元素挨个拷贝进新数组
  2. 在这里要想把插入的数插入到对应的位置上,新旧两个数组的下标就不能同时增长,要定义两个变量i和j
    2.1 当新数组下标值i不等于index时,i和j同时增长,旧数组的元素挨个拷贝进新数组
    2.2 当新数组下标值i等于index时,j不增长,也就是旧数组中的下标不进行移动,把插入值赋给arrNew[i](下标:一个++,一个不动)
public class HelloWorld {
    public static void main(String []args) {
		int[] arr = {10,12,45,90};
		//1. 顺序查找,看添加的数要放在数组的哪个位置上
		int findName = 23;//可以变成输入,这里不变了
		//这是一个接收/判断变量
		int index = -1;
		for(int i = 0;i < arr.length;i++){
			/*1.1 输入的数和数组元素进行比较,将该数插到第一个大于该数的数组元素的位置上
			      findName <= arr[i]时,插入的下标为i */
			if(findName <= arr[i]){
				index = i;
				break;
			}
		}
		/*1.2 判断index的值,来判断输入的数是否找到了自己的位置
		      findName <= arr[i]不成立,则插入到最后位置*/
		if(index == -1){
			index = arr.length;
		}
		//2. 数组扩容
		//将输入的数插到指定位置
		int[] arrNew = new int[arr.length+1];
		for(int i = 0,j = 0;i < arrNew.length;i++){
			if(i != index){
				arrNew[i] = arr[j];
				j++;
			}else{
				arrNew[i] = findName;
			}
		}
		arr = arrNew;
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i]+"\t");
		}
    }
}

三 . 随机生成10个数字存入数组,倒序打印,求平均值,max及其下标并查找里面有没有8

  1. 要求
    在这里插入图片描述
  2. 代码
public class HelloWorld {
    public static void main(String []args) {
		//随机生成10个数字存入数组
		int[] arr = new int[10];
		double avg = 0;
		double sum = 0;
		for(int i = 0;i < arr.length;i++){
			arr[i] = (int)(Math.random() * 100 + 1);
			sum += arr[i];
		}
		System.out.println("======生成的数组为======");
		for(int i = 0;i < arr.length;i++){
			System.out.print(arr[i]+"\t");
		}
		System.out.println();
		//倒序打印
		int[] arrNew = new int[10];
		for(int i = 0,j = arrNew.length - 1;i < arrNew.length;i++,j--){
			arrNew[i] = arr[j];
		}
		System.out.println("======倒序后的数组为======");
		for(int i = 0;i < arrNew.length;i++){
			System.out.print(arrNew[i]+"\t");
		}
		System.out.println();
		//计算平均值(注意精度)
		avg = sum / arr.length;
		System.out.println("======数组元素的平均值为======");
		System.out.println("平均值 = " + avg);
		//求最大值及其下标
		int max = arr[0];
		int index = 0;
		for(int i = 1;i < arr.length;i++){
			if(arr[i] > max){
				max = arr[i];
				index = i;
			}
		}
		System.out.println("======数组元素的最大值及其下标为======");
		System.out.println("最大值 = " + max);
		System.out.println("最大值下标 = " + index);
		//查找数组中是否有8(减少数据耦合,所以另外定义findNum而不是在程序中直接写8)
		//为了让没找到时输出:没找到,所以定义了一个变量来判断(找到改变该值,没找到不改变)
		int findNum = 8;
		int index1 = -1;
		for(int i = 1;i < arr.length;i++){
			if(findNum == arr[i]){
				System.out.println("======数组元素的是否有8======");
				System.out.println("找到数"+findNum+"下标为"+index1);
				break;
			}
		}
		if(index1 == -1){
			System.out.println("没有找到数"+findNum);
		}
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值