7-Java数组

数组

  • 为什么需要数组? 数组的引入,传统方法解决问题不灵活
// 数组的引出
// 如果有600只鸡,需要定义600多个变量,用传统方法虽然可以解决,但是没有灵活性

public class Array01{

	public static void main(String[] args) {
		
		/*
		一个养鸡场有 6 只鸡,它们的体重分别是 3kg,5kg,1kg,3.4kg,2kg,50kg 。
		请问这六只鸡的总体重是多少? 平均体重是多少? 请你编一个程序。
		思路分析:定义6个变量
		平均体重是: 总体重 / 6
		 */
		double hen1 = 3;
		double hen2 = 5;
		double hen3 = 1;
		double hen4 = 3.4;
		double hen5 = 2;
		double hen6 = 50;

		double totalWeight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
		double avgWeight = totalWeight / 6;

		System.out.println("总体重:" + totalWeight + " 平均体重:" + avgWeight);
		
	}
}
  • 数组介绍
    数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型
  • 数组快速入门
// 数组的引出
// 如果有600只鸡,需要定义600多个变量,用传统方法虽然可以解决,但是没有灵活性

public class Array01{

	public static void main(String[] args) {
		
		/*
		一个养鸡场有 6 只鸡,它们的体重分别是 3kg,5kg,1kg,3.4kg,2kg,50kg 。
		请问这六只鸡的总体重是多少? 平均体重是多少? 请你编一个程序。
		思路分析:定义6个变量
		平均体重是: 总体重 / 6
		 */
		// double hen1 = 3;
		// double hen2 = 5;
		// double hen3 = 1;
		// double hen4 = 3.4;
		// double hen5 = 2;
		// double hen6 = 50;

		// double totalWeight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
		// double avgWeight = totalWeight / 6;

		// System.out.println("总体重:" + totalWeight + " 平均体重:" + avgWeight);
		// 比如,我们用数组来解决一个问题
		// 定义一个数组
		// double[] 是double类型的数组,数组名是hens
		// {3, 5, 1, 3.4, 2, 50};表示数组的值/元素
		// 
		double[] hens = {3, 5, 1, 3.4, 2, 50, 7.8, 8.0};
		// 遍历数组得到数组所有元素
		// 1、我们可以通过hens[下标]来访问数组的元素
		// 比如:下标是从0开始编号的,比如第一个元素是hens[0]
		// 2.我们可以for循环,访问数组的所有的元素和值
		// 3.使用一个变量 totalWeight 就可以累计所有的值
		System.out.println("数组的长度:" + hens.length);
		double totalWeight = 0;
		for(int i = 0; i < hens.length; i++){
			System.out.println("第"+ i + "个元素的值为:" + hens[i]);
			totalWeight += hens[i];
		}
		System.out.println("总体重:" + totalWeight +  " 平均体重:" + (totalWeight / hens.length));
	}
}
  • 数组的使用
import java.util.Scanner;

public class Array02{

	public static void main(String[] args) {
		
		//循环输入 5 个成绩,保存到 double 数组,并输出
		double scores[] = new double[5];
		System.out.println("循环输入5个成绩");
		Scanner myScanner = new Scanner(System.in);

		for (int i = 0; i < scores.length; i++){
			System.out.println("请输入第" + (i + 1) + "个数字:");
			scores[i] = myScanner.nextDouble();

		}
		System.out.println("循环输出5个数据:");

		for(int i = 0; i < scores.length; i++){
			System.out.println("第" + (i + 1) + "个数据是:" + scores[i]);
		}

		
	}
}
  • 静态初始化
    int[] a = {1, 2, 3}
    int a[] = new int[3];
    int[] a;
    a = new int[4];
  • 数组的细节
public class ArrayDetail{
	public static void main(String[] args) {
		
		// 1.数组是多种数据类型的组合,可以实现对数据的统一管理
		// 
		// 
		// int[] arr1 = {1, 2, 3, 60, "hello"}; // 报错,类型不一致且没有办法自动转换
		double[] arr2 = {1.1, 2.2, 3.3, 60.0, 22}; // 可以,因为可以自动转换
		// 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
		String[] arr3 = {"北京", "Jack", "mailln"};
		// 数组创建后,如果没有赋值,有默认值
		// int, short, byte, long, 0
		// float, double 0.0
		// char \u0000.
		// boolean false
		// String null
		short[] arr4 = new short[3];
		for(int i = 0; i < arr4.length; i++){
			System.out.println(arr4[i]);
		}
		// 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值 3 使用数组
		// 数组的下标是从 0 开始的
		// 数组下标必须在指定范围内使用,否则报:下标越界异常,比如
		// 数组的最大值是长度减一
		int[] arr = new int[5];
		System.out.println(arr[5]);

		// 数组属引用类型,数组型数据是对象(object)
	}
}
  • 数组练习1
    创建一个 char 类型的 26 个元素的数组,分别 放置'A'-'Z'。
    使用 for 循环访问所有元素并打印出来 提示:char 类型 数据运算 'A'+2 -> 'C'
//创建一个 char 类型的 26 个元素的数组,分别 放置'A'-'Z'。
//使用 for 循环访问所有元素并打印出来 提示:char 类型 数据运算 'A'+2 -> 'C' ArrayExercise01.java

public class ArrayEx01{

	public static void main(String[] args) {
		/*
		思路分析:1.定义一个数组,char[] chars = new char[26];
		2. 因为 'A' + 1 = 'B'; 使用for赋值
		3. 使用for循环访问所有元素

		 */
		char[] characters = new char[25];
		char j='A';
		for(int i = 0; i< characters.length; i++){
			characters[i] = (char)(j + i); // 'A' + i 是int,需要强制转换
		}

		for (int i=0; i < characters.length; i++){
			System.out.print(characters[i] + " ");
		}
	}
}
  • 数组练习2
    请求出一个数组 int[]的最大值 {4,-1,9, 10,23},并得到对应的下标
//请求出一个数组 int[]的最大值 {4,-1,9, 10,23},并得到对应的下标
//
public class ArrayEx02{
	public static void main(String[] args) {
		
		int[] nums = {4, -1, 9, 10, 23};
		/*
		思路分析:定义一个最大值为数组第一个值, int maxNum = nums[0];
		1. 循环遍历所有的数,如果比第一个数大,则赋值给最大值
		 */
		int maxNum = nums[0];
                int maxIndex = 0;
		for (int i = 0; i < nums.length; i++){
			if (nums[i] > maxNum){
				maxNum = nums[i];
                                maxIndex = i;
			}
		}
		System.out.println("数组的最大值:" + maxNum);
	}
}
  • 练习3
    请求出一个数组的和和平均值。
// 请求出一个数组的和和平均值。
//
public class ArrayEx02{
	public static void main(String[] args) {
		
		int[] nums = {4, -1, 9, 10, 23};
		/*
		思路分析:
		1. 循环遍历所有的数,加起来
		*/
		int sum = 0;

		for (int i = 0; i < nums.length; i++){
			sum += nums[i];
		}

		System.out.println("数组的和:" + sum + " 数组的平均值:" + sum*1.0/nums.length);
	}
}

数组的赋值机制

  1. 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。 int n1 = 2; int n2 = n1;
  2. 数组在默认情况下是引用传递,赋的值是地址
  3. 可以看到两者的区别

public class ArrayAssign{
	public static void main(String[] args) {
		
		//基本数据类型赋值, 赋值方式为值拷贝
		//n2的变化不会影响到n1
		
		int n1 = 10;
		int n2 = n1;

		n2 = 80;
		System.out.println("n1=" + n1);
		System.out.println("n2=" + n2);

		// 数组在默认情况下是引用分配,赋值的是地址,赋值方式是引用传达
		// 是一个地址,arr2的变化会影响到 arr1
		
		
		int[] arr1 = {1, 2, 3};
		int[] arr2 = arr1;

		arr2[0] = 10;
		System.out.println("=======arr1的元素=======");
		for(int i = 0; i<arr1.length; i++){
			System.out.print(arr1[i] + " ");
		}

		System.out.println("\n=======arr2的元素=======");
		for(int i = 0; i < arr2.length; i++){
			System.out.print(arr2[i] + " ");
		}
		
	}
}
  • 内存的空间图
  • 得到一个新的数组,不影响原来的数组,数组拷贝,要求数据空间是独立的

public class ArrayCopy{

	public static void main(String[] args) {
		
		// 将 int[] arr1 = {10,20,30}; 拷贝到 arr2 数组, 要求数据空间是独立的.
		int[] arr1 = {10, 20, 30};

		// 先创建一个新的数组,arr2,开辟新的数据空间
		int[] arr2 = new int[arr1.length];

		for(int i = 0; i < arr1.length; i++){
			arr2[i] = arr1[i];
		}
		arr2[0] = 30;

		System.out.println("=====打印arr1d值=======");

		for(int i = 0; i < arr1.length; i++){
			System.out.print(arr1[i] + " ");
		}
	}
}

数组翻转

要求:把数组的元素内容反转。

// 要求:把数组的元素内容反转
// 
public class ArrayReverse{
	public static void main(String[] args) {
		// 通过找规律反转
	
		// 通过逆序赋值的方式
		int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};

		int start = 0;
		int end = arr1.length - 1;
		int temp = 0;

		while (start < end){

			temp = arr1[start];
			arr1[start] = arr1[end];
			arr1[end] = temp;
			start++;
			end--;
		}

		// 类始于第一种方式,但是用for循环
		int len = arr1.length;
		int temp = 0;
		for (int i = 0; i < len/2; i++){
			temp = arr1[i];
			arr1[i] = arr1[len-1-i];
			arr1[len-i-1] = temp;

		}

		for(int i=0; i < arr1.length; i++){
			System.out.print(arr1[i] + " ");
		}


		// 通过创建一个新的交换空间
		int[] arr2 = new int[arr1.length];

		for(int i = 0; i < arr1.length; i++){
			arr2[i] = arr1[arr1.length-1-i];
		}

		for(int i = 0; i < arr2.length; i++){
			System.out.print(arr2[i] + " ");
		}
	}
}

数组的扩容

  1. 原始数组使用静态分配 int[] arr =
  2. 增加的元素 4,直接放在数组的最后 arr =
  3. 用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
// 实现动态的给数组添加元素效果,实现对数组扩容
import java.util.Scanner;
public class ArrayAdd{
	public static void main(String[] args) {
		
		/*
		思路: while True, 不添加跳出 break
		2. 每次创建一个新的数组,在之前的数据数量增加一个数据
		3. 添加成功,提示是否继续
		1) 原始数组使用静态分配 int[] arr = {1,2,3} 
		2) 增加的元素 4,直接放在数组的最后 arr = {1,2,3,4} 
		3) 用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
		 */
		int[] arr = {1, 2, 3};
		Scanner myScanner = new Scanner(System.in);
		int[] arrNew = arr;
		while(true){
			System.out.println("是否需要添加数组元素(y/n):");
			char chara = myScanner.next().charAt(0);
			if (chara == 'y'){
				arrNew = new int[arr.length + 1];
				System.out.println("输入添加的数字:");
				int num = myScanner.nextInt();
				for (int i = 0; i < arr.length; i++){
					arrNew[i] = arr[i]; 
				}
				arrNew[arrNew.length-1] = num;
				arr = arrNew;

			}
			else{
				System.out.println("不需要添加了,结束");
				break;
			}

		}

		for (int i = 0; i < arrNew.length; i++){
			System.out.print(arrNew[i] + " ");
		}

	}
}
  • 数据缩减
    有一个数组 {1, 2, 3, 4, 5}, 可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后那个元素。
    当只剩 下最后一个元素,提示,不能再缩减
// 有一个数组 {1, 2, 3, 4, 5}, 可以将该数组进行缩减,提示用户是否继续缩减,
// 每次缩减最后那个元素。当只剩 下最后一个元素,提示,不能再缩减
import java.util.Scanner;

public class ArrayReduce{
	public static void main(String[] args) {
		
		/*
		思路:
		1.缩减需要定义一个新数组
		2.新数组的长度比原数组减一
		3.原数组指向新数组
		 */
		
		int[] arr = {1, 2, 3, 4, 5};
		int[] arrNew = arr;
		Scanner myScanner = new Scanner(System.in);

		while(true){
			System.out.println("是否要缩减数组(y/n):");
			char chara = myScanner.next().charAt(0);
			if (chara == 'y'){
				if (arr.length == 1){
					System.out.println("只剩下最后一个元素,不能再缩减");
					break;
				}
				arrNew = new int[arr.length-1];
				for(int i =0; i < arrNew.length; i++){
					arrNew[i] = arr[i];
				}
				arr = arrNew;

			}
			else{
				break;
			}

		}

		for(int i=0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}


	}
}

排序

排序是将多个数据,依指定的顺序进行排列的过程。 排序的分类:

  • 内部排序: 指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择 式排序法和插入式排序法)
  • 数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
    冒泡排序
    冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素 的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
 
 public class BubbleSort{
 	public static void main(String[] args) {
 		/*
 		思路:每一次循环都要确定最大的数,放到最后
 		1. 第一轮循环确定最后的数是最大的,每相邻两个数进行比较,如果前面的数大于后面的数,进行交换
 		2. 循环的次数是 arr.length - 1;

 		 */
 		int[] arr = {24, 69, 80, 57, 13};
 		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] > arr[j+1]){
 					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] + " ");
 		}
 	}
 }

查找

  • 顺序查找
import java.util.Scanner;

public class SeqSearch{
	public static void main(String[] args) {
		// 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏: 
		// 从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
		/*
		思路:
		遍历数组,
		逐个比较,如果相等,break退出
		 */
		String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
		Scanner myScanner = new Scanner(System.in);
		int index = -1;
		label1:
		do{
			System.out.println("请输入名字:");
			String name = myScanner.next();
			label2:
			for(int i =0; i < names.length; i++){
				if(name.equals(names[i])){
					System.out.println("找到了" + name);
					System.out.println("下标=" + i);
					index = i;
					break label1;
				}
			}
			if (index == -1){
				System.out.println("sorry, 没有找到" + name);
			}

		}while(true);

		
	}
}
  • 二分查找

多维数组

  • 多维数组我们介绍二维数组
  • 比如棋盘就是一个二维数组
  • 快速入门
    请用二维数组输出如下图形
    0 0 0 0 0 0
    0 0 1 0 0 0
    0 2 0 3 0 0
    0 0 0 0 0 0
public class TwoDimensionalArray01{
	public static void main(String[] args) {
		
		/*
		请用二维数组输出如下图形 
		0 0 0 0 0 0 
		0 0 1 0 0 0 
		0 2 0 3 0 0 
		0 0 0 0 0 0
		 */
		// 什么是二维数组
		// 从定义形式看 int[][]
		// 可以理解为原来的每个数组是 一维数组,就构成二维数组
		
		int[][] arr = {{0, 0, 0, 0, 0, 0},
					   {0, 0, 1, 0, 0, 0},
					   {0, 2, 0, 3, 0, 0},
					   {0, 0, 0, 0, 0, 0},
					};

		// 输出二维数组
		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();
		}
	}
}
  • 数组的练习
    已知有个升序的数组,要求插入一个元素,该数组依然是升序的
import java.util.Scanner;

public class  Homework04{
	public static void main(String[] args) {
		/*
		有个升序的数组,{10, 12, 23, 45, 90}, 插入一个数字后,仍然保持升序
		思路: 定义插入的int insertNum , 找到插入的位置
		将元素组的数据都复制到新数组,

		 */
		Scanner myScanner = new Scanner(System.in);

		int arr[] = {10, 12, 23, 45, 90};

		int tempPath = -1;
		int[] newArr;

		System.out.println("请输入插入数字:");
		int insertNum = myScanner.nextInt();

		// 要赋值到新数组, 同时将小于该数的值赋值到新数组中
		// 找到要赋值的位置
		newArr = new int[arr.length+1];

		// 笨的办法就是插入到最后,然后在冒泡排序
		// 聪明的办法是找到比他的大的值,然后移动
		/*
		要一个一个的移动到新数组中的循环是
		先找到要插入的值的位置
		 */
		
		for(int i = 0; i < arr.length; i++){
			if(insertNum < arr[i]){
				tempPath = i;
				break;
			}
		}
		if (tempPath == -1){
			tempPath = arr.length;
		}

		for(int i=0, j=0; i < newArr.length; i++){

			if(tempPath == i){
				newArr[i] = insertNum;
			}
			else{
				newArr[i] = arr[j];
				j++;
			}

		}

		System.out.println("====插入后的新数组的值======");
		for(int i = 0; i < newArr.length; i++){
			System.out.print(newArr[i] + " ");
		}
		
	

	}
}
  • 数组练习
    求数组的最大值和下标,平均数和求和


public class Homework05{
	public static void main(String[] args) {
		
		/*
		随机生成10个整数(1-100)保存到数组
		并倒序打印以及求出平均值,求最大值和最小值的下标
		并查找里面是否有8
		 */
		
		int[] arr = new int[10];
		for(int i=0; i < arr.length; i++){
			arr[i] = (int)(Math.random() * 100) + 1;
		}

		// 
		System.out.println("====arr的元素情况====");
		for(int i=0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println("\n=====arr逆序打印=======");
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[arr.length-1-i] + " ");
		}

		// 求最大值的下标和求和
		int sum = 0;
		int maxIndex = 0;
		int maxNum = arr[0];
		for(int i = 0; i < arr.length; i++){
			sum += arr[i];
			if(arr[i] > maxNum){
				maxNum = arr[i];
				maxIndex = i;
			}
		}

		System.out.println("求和:" + sum + " 平均值:" + sum/(arr.length * 1.0));
		System.out.println("最大值:" + maxNum + " 最大值下标:" + maxIndex);

		int findNum = 8;
		int findIndex = -1;

		for(int i = 0; i < arr.length; i++){
			if(arr[i] == findNum){
				System.out.println("找到了" + findNum + " 下标:" + i);
				findIndex = i;
				break;
			}
		}
		if(findIndex == -1){
			System.out.println("没有找到这个数");
		}

	}
}
  • 数组练习
    写出冒泡排序法,从小到大
public class Homework06{
	public static void main(String[] args) {
		
		int arr[] = {20, 12, 8, 79, 45, 90};

		int temp = 0;

		for(int i = 0; i < arr.length; i++){
			for (int j = 0; j < arr.length-1-i; j++){
				if(arr[j] > arr[j+1]){
					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] + " ");
		}
	}
}
posted @ 2021-12-09 21:46  心远志高  阅读(41)  评论(0编辑  收藏  举报