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

第六章:数组排序查找

  • 总体内容
  • 数组
    • 数组的介绍
    • 数组的具体使用
      • 数组的定义和引用
      • 数组的细节
      • 数组练习
        • 练习1:字符数组存入A-Z(唯一注意:要强制类型转换)
        • ※练习2:求数组中的最大值,以及对应下标
    • 数组的赋值机制(内存布局)
      • 数组拷贝(内容一致,地址独立)
    • 数组反转
      • 1. 方法一:找规律交换
      • 2. 方法二:逆序赋值法(逆序拷贝+指向同一地址)
    • 数组扩容和缩减(动态添加或缩减元素)
      • 数组扩容(对数组拷贝的应用)
      • 数组缩减
  • 排序(主要介绍冒泡排序)
    • 排序的介绍
    • 冒泡排序
      • 介绍
      • 冒泡排序的案例
        • 冒泡排序解析(从后向前)以及特点总结
        • ※冒泡排序代码实现(后到前和前到后)
  • 查找(主要介绍顺序查找)
    • 查找的介绍
    • 顺序查找案例
  • 多维数组-二维数组
    • 二维数组介绍及快速入门案例
    • 二维数组的使用
      • 动态初始化1(不写具体赋值)
        • 1. 语法
        • 2. ※二维数组内存布局
      • 动态初始化2(不写具体赋值)
        • 1. 语法
        • 2. 案例(※每个一维数组个数不一样)
      • 静态初始化(不写new)
      • 二维数组的细节
    • 二维数组的案例--杨辉三角
      • 小练习
  • 本章案例练习
    • 一. 定义语法练习(好好看)
    • 二. ※升序数组插入一个值,该数组仍升序(2种方法)
    • 三 . 随机生成10个数字存入数组,倒序打印,求平均值,max及其下标并查找里面有没有8

总体内容

数组:array
java学习笔记-第六章:数组排序查找_第1张图片

数组

数组的介绍

  1. 数组是引用数据类型
  2. 数组用于存储一组同一类型的数据
    在这里插入图片描述
  3. 数组的一个入门例子
    3.1 定义一个数组:
    java学习笔记-第六章:数组排序查找_第2张图片
    3.2 获取数组中的数据
    在这里插入图片描述
    3.3 遍历整个数组,累计数组中的值
    用3.4进行改进
    在这里插入图片描述
    3.4 获取数组的长度:数组.length
    java学习笔记-第六章:数组排序查找_第3张图片

数组的具体使用

数组的定义和引用

  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 循环输入
    java学习笔记-第六章:数组排序查找_第4张图片
    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类型
java学习笔记-第六章:数组排序查找_第5张图片

※练习2:求数组中的最大值,以及对应下标
  1. 思路:
    1.1 假定数组第一个值是最大值,max=arr[0],maxIndex=0
    1.2 从下标1开始遍历数组,如果max<当前元素,就max=当前元素,maxIndex=当前下标
  2. 代码
    java学习笔记-第六章:数组排序查找_第6张图片

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

  1. 基本类型的赋值和引用类型的赋值不同
    1.1. 基本类型是传值赋的值只是数值)–>值拷贝/传递
    1.2 引用类型是传址赋的值是地址)–>引用传递
  2. 基本类型指向值,引用类型指向地址(用内存解释)
    java学习笔记-第六章:数组排序查找_第7张图片

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

在这里插入图片描述
java学习笔记-第六章:数组排序查找_第8张图片
使用new来开辟新空间
java学习笔记-第六章:数组排序查找_第9张图片

数组反转

1. 方法一:找规律交换

1.1重点是思路(找规律):
java学习笔记-第六章:数组排序查找_第10张图片
1.2. 代码(循环的次数,交换的两值以及如何交换)(缺少一个遍历,不写了)
java学习笔记-第六章:数组排序查找_第11张图片

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

for循环定义了两个变量(一个向前一个向后)
java学习笔记-第六章:数组排序查找_第12张图片

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

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

  1. 数组扩容要求
    1.1 动态给数组添加元素(数组扩容)
    1.2 静态数组,添加的元素4放在数组最后
    1.3 是否继续添加
    java学习笔记-第六章:数组排序查找_第13张图片
  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被销毁
    java学习笔记-第六章:数组排序查找_第14张图片
    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时跳出循环
    java学习笔记-第六章:数组排序查找_第15张图片

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

排序的介绍

java学习笔记-第六章:数组排序查找_第16张图片

冒泡排序

介绍

java学习笔记-第六章:数组排序查找_第17张图片

冒泡排序的案例

在这里插入图片描述

冒泡排序解析(从后向前)以及特点总结
  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. 二维数组的定义
    java学习笔记-第六章:数组排序查找_第18张图片
  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. ※二维数组内存布局

二维数组在栈中指向堆中的一块地址,这个地址中保存了二维数组的两个元素(两个一维数组)的地址,这两个地址中保存了一维数组的元素
java学习笔记-第六章:数组排序查找_第19张图片

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

1. 语法

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

2. 案例(※每个一维数组个数不一样)
  1. 先声明有3个一维数组,但是此时一维数组没有指向任何地址(没有开辟空间)
  2. 等到循环中,再为每一个一维数组开辟空间:arr[i]表示第几个一维数组,为一维数组开辟空间用到了new 类型[大小]arr[i]=new int[i+1]
    java学习笔记-第六章:数组排序查找_第20张图片

静态初始化(不写new)

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

二维数组的细节

java学习笔记-第六章:数组排序查找_第21张图片

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

  1. 要求
    java学习笔记-第六章:数组排序查找_第22张图片
  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. 运行结果
    java学习笔记-第六章:数组排序查找_第23张图片

小练习

java学习笔记-第六章:数组排序查找_第24张图片

本章案例练习

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

java学习笔记-第六章:数组排序查找_第25张图片

二. ※升序数组插入一个值,该数组仍升序(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 再进行扩容
    java学习笔记-第六章:数组排序查找_第26张图片

顺序查找有两种情况

  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);
		}
    }
}

你可能感兴趣的:(java基础学习笔记,java,开发语言,后端)