【Java】基础编程篇(3.数组)

前言

尚硅谷 - Java课程 - 笔记(用于自己复习)
终于把数组看完了,总结一下,继续冲~

一、数组概述

1.数组的理解:

数组(Array),是多个相同类型数据一定顺序排列的集合,使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

2.数组相关的概念:

  • 数组名
  • 元素
  • 角标、下标、索引
  • 数组的长度:元素的个数

3.数组的特点:

  • 数组属于引用数据类型的变量。
  • 数组的元素,既可以是基本数据类型,也可以是引用数据类型
  • 创建数组对象会在内存中开辟一整块连续的空间
  • 数组的长度一旦确定,就不能修改。

4. 数组的分类:

① 按照维数:一维数组、二维数组、。。。
② 按照数组元素的类型基本数据类型元素的数组、引用数据类型元素的数组

5. 数据结构:

1.数据与数据之间的逻辑关系:集合、一对一、一对多、多对多
2.数据的存储结构:

  • 线性表(一对一):顺序表(比如:数组)、链表、栈、队列
  • 树形结构(一对多):二叉树
  • 图形结构(多对多)

6. 算法:

  • 排序算法
  • 搜索算法

二、一维数组

1.一维数组的声明与初始化

正确的方式:
 int num;//声明
 num = 10;//初始化
 int id = 1001;//声明 + 初始化
 int[] ids;//声明
 
 //1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
 ids = new int[]{1001,1002,1003,1004};
 
 //1.2 动态初始化:数组的初始化和数组元素的赋值操作分开进行
 String[] names = new String[5];
 int[] arr4 = {1,2,3,4,5};//类型推断
错误的方式:
 int[] arr1 = new int[];
 int[5] arr2 = new int[5];
 int[] arr3 = new int[3]{1,2,3};

2.一维数组元素的引用

  • 定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;
  • 数组元素的引用方式:数组名[数组元素下标]
  • 通过角标的方式调用。
//数组的角标(或索引从0开始的,到数组的长度-1结束。
		names[0] = "王铭";
		names[1] = "王赫";
		names[2] = "张学良";
		names[3] = "孙居龙";
		names[4] = "王宏志";//charAt(0)

3.数组的属性:length

System.out.println(names.length); //5
System.out.println(ids.length);

说明

数组一旦初始化,其长度就是确定的。arr.length
数组长度一旦确定,就不可修改。

4.一维数组的遍历

for(int i = 0;i < names.length;i++){
	System.out.println(names[i]);
}

5.一维数组元素的默认初始化值

在这里插入图片描述

  • 数组元素是整型:0
  • 数组元素是浮点型:0.0
  • 数组元素是char型:0或’\u0000’,而非’0’
  • 数组元素是boolean型:false
  • 数组元素是引用数据类型:null

6.一维数组的内存结构

在这里插入图片描述

二、二维数组

1.如何理解二维数组?

  • 数组属于引用数据类型
  • 数组的元素也可以是引用数据类型
  • 一个一维数组A的元素如果还是一个一维数组类型的,则,此数组A称为二维数组。

2.二维数组的声明与初始化

正确的方式:
int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};//类型推断
错误的方式:
String[][] arr4 = new String[][4];
String[4][3] arr5 = new String[][];
int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};

3.如何调用二维数组元素:

System.out.println(arr1[0][1]); //2
System.out.println(arr2[1][1]); //null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
System.out.println(arr3[0]);

4.二维数组的属性:

System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//4

5.遍历二维数组元素

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

6.二维数组元素的默认初始化值

规定:二维数组分为外层数组的元素,内层数组的元素

int[][] arr = new int[4][3];

  • 外层元素:arr[0],arr[1]等
  • 内层元素:arr[0][0],arr[1][2]等

数组元素的默认初始化值
针对于初始化方式一:比如:int[][] arr = new int[4][3];

  • 外层元素的初始化值为:地址值
  • 内层元素的初始化值为:与一维数组初始化情况相同

针对于初始化方式二:比如:int[][] arr = new int[4][];

  • 外层元素的初始化值为:null
  • 内层元素的初始化值为:不能调用,否则报错。

7.二维数组的内存结构

在这里插入图片描述

三、数组的常见算法

1.数组的创建与元素赋值:

杨辉三角(二维数组)、回形数(二维数组)、6个数,1-30之间随机生成且不重复。

1.1 杨辉三角

使用二维数组打印一个 10 行杨辉三角

  1. 第一行有 1 个元素, 第 n 行有 n 个元素
  2. 每一行的第一个元素和最后一个元素都是 1
  3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。
    即:yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
代码如下:
package com.atguigu.exer;
public class YangHuiTest {
	public static void main(String[] args) {
		//1.声明并初始化二维数组      动态初始化
		int[][] yangHui = new int[10][];

		//2.给数组的元素赋值
		for(int i=0;i<yangHui.length;i++){
			//yangHui[0] = new int[1]; //第一行有 1 个元素, 第 n 行有 n 个元素
			//yangHui[1] = new int[2];
			yangHui[i] = new int[i+1];
			
			//2.1给首末元素赋值
			yangHui[i][0] = yangHui[i][i] = 1;
			
			//2.2给每行的非首末元素赋值 从i=2开始
			if(i>1){ //可以去掉
				//内层循环,从第二列开始j=1,因为是非首末元素,j小于当前行的列数-1,
				for(int j=1;j<yangHui[i].length - 1;j++){ 
					yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
				}
			}
		}
		
		//3.遍历二维数组
		for(int i=0;i<yangHui.length;i++){
			for(int j=0;j<yangHui[i].length;j++){
				System.out.print(yangHui[i][j] + " ");
			}
			System.out.println();//换行
		}
		
	}
}
1.2 创建一个长度为6的int型数组,要求取值为1-30,同时元素值各不相同

思路:
要求:所有随机数都是两位数。[10,99]公式:(int) (Math.random() * (99-10+1) + 10)

提示:[0,1) * 90 -> [0,90) + 10 -> [10,100) ->[10,99] (int)(Math.random() * 90 + 10)
[1,30] : (int) (Math.random() * 30) + 1

代码如下:
class ArrayExer {
	public static void main(String[] args) {
		//方式一:
//		int[] arr = new int[6];
//		for (int i = 0; i < arr.length; i++) {// [0,1) [0,30) [1,31)
//			arr[i] = (int) (Math.random() * 30) + 1;
//
//			boolean flag = false;
//			while (true) {
//				for (int j = 0; j < i; j++) {
//					if (arr[i] == arr[j]) {
//						flag = true;
//						break;
//					}
//				}
//				if (flag) {
//					arr[i] = (int) (Math.random() * 30) + 1;
//					flag = false;
//					continue;
//				}
//				break;
//			}
//		}
//
//		for (int i = 0; i < arr.length; i++) { //遍历
//			System.out.println(arr[i]);
//		}

		//方式二:
		int[] arr = new int[6];
		for (int i = 0; i < arr.length; i++) {  // [0,1) [0,30) [1,31)
			arr[i] = (int) (Math.random() * 30) + 1;
			
				for (int j = 0; j < i; j++) {
					if (arr[i] == arr[j]) {
						i--;
						break;
					}
				}
			}

		for (int i = 0; i < arr.length; i++) {//遍历
			System.out.println(arr[i]);
		}
	}
}
1.3 回形数(二维数组)

从键盘输入一个整数(1~20)
则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。例如: 输入数字2,则程序输出:

1 2 
4 3 

输入数字3,则程序输出:

1 2 3 
8 9 4 
7 6 5 

输入数字4, 则程序输出:

1   2   3   4 
12  13  14  5 
11  16  15  6 
10  9   8   7
//方式一:
class RectangleTest {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("输入一个数字");
		int len = scanner.nextInt();
		int[][] arr = new int[len][len];

		int s = len * len;
		/*
		 * k = 1:向右 k = 2:向下 k = 3:向左 k = 4:向上
		 */
		int k = 1;
		int i = 0, j = 0;
		for (int m = 1; m <= s; m++) {
			if (k == 1) {
				if (j < len && arr[i][j] == 0) {
					arr[i][j++] = m;
				} else {
					k = 2;
					i++;
					j--;
					m--;
				}
			} else if (k == 2) {
				if (i < len && arr[i][j] == 0) {
					arr[i++][j] = m;
				} else {
					k = 3;
					i--;
					j--;
					m--;
				}
			} else if (k == 3) {
				if (j >= 0 && arr[i][j] == 0) {
					arr[i][j--] = m;
				} else {
					k = 4;
					i--;
					j++;
					m--;
				}
			} else if (k == 4) {
				if (i >= 0 && arr[i][j] == 0) {
					arr[i--][j] = m;
				} else {
					k = 1;
					i++;
					j++;
					m--;
				}
			}
		}

		// 遍历
		for (int m = 0; m < arr.length; m++) {
			for (int n = 0; n < arr[m].length; n++) {
				System.out.print(arr[m][n] + "\t");
			}
			System.out.println();
		}
	}
}
//方式二:
class RectangleTest1 {
	public static void main(String[] args) {
		int n = 7;
		int[][] arr = new int[n][n];

		int count = 0; // 要显示的数据
		int maxX = n - 1; // x轴的最大下标
		int maxY = n - 1; // Y轴的最大下标
		int minX = 0; // x轴的最小下标
		int minY = 0; // Y轴的最小下标
		while (minX <= maxX) {
			for (int x = minX; x <= maxX; x++) {
				arr[minY][x] = ++count;
			}
			minY++;
			for (int y = minY; y <= maxY; y++) {
				arr[y][maxX] = ++count;
			}
			maxX--;
			for (int x = maxX; x >= minX; x--) {
				arr[maxY][x] = ++count;
			}
			maxY--;
			for (int y = maxY; y >= minY; y--) {
				arr[y][minX] = ++count;
			}
			minX++;
		}

		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr.length; j++) {
				String space = (arr[i][j] + "").length() == 1 ? "0" : "";
				System.out.print(space + arr[i][j] + " ");
			}
			System.out.println();
		}
	}
}

2.针对于数值型的数组

算法的考查:求数值型数组中元素的最大值、最小值、平均数、总和等

  • 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
  • 然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
  • 要求:所有随机数都是两位数。[10,99]公式:(int) (Math.random() * (99-10+1) + 10)

提示:

 [0,1) * 90 -> [0,90) + 10 -> [10,100) ->[10,99]
 (int)(Math.random() * 90 + 10)
实现代码如下:
package com.atguigu.java;
public class ArrayTest1 {
	public static void main(String[] args) {
		//数组调出来
		int[] arr = new int [10];
		for(int i=0;i<arr.length;i++){
			arr[i]= (int) (Math.random() * (99-10+1) + 10);	
		}
		
		//遍历
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i] + "\t");
		}
		System.out.println();//换行
		
		//求数组元素的最大值
		int maxValue = arr[0]; 
		for(int i = 1;i<arr.length;i++){
			if(maxValue < arr[i]){
				maxValue = arr[i];
			}
		}
		System.out.println("最大值为:" + maxValue);
		
		//求数组元素的最小值
		int minValue = arr[0];
		for(int i = 1;i<arr.length;i++){
			if(minValue > arr[i]){
				minValue = arr[i];
			}
		}
		System.out.println("最小值为:" + minValue);
		
		//求数组元素的总和
		int sum = 0;
		for(int i = 0;i<arr.length;i++){
			sum += arr[i];
		}
		System.out.println("总和为:" + sum);
		
		//求数组元素的平均数
		int avgValue = sum / arr.length;
		System.out.println("平均数为:" + avgValue);
	}
}

3.数组的赋值与复制

int[] array1,array2;
array1 = new int[]{1,2,3,4};
3.1赋值:
array2 = array1;

如何理解:将array1保存的数组的地址值赋给了array2,使得array1和array2共同指向堆空间中的同一个数组实体。
在这里插入图片描述

3.2 复制:
array2 = new int[array1.length];
for(int i = 0;i < array2.length;i++){
array2[i] = array1[i];
}

如何理解:我们通过new的方式,给array2在堆空间中新开辟了数组的空间。将array1数组中的元素值一个一个的赋值到array2数组中。
在这里插入图片描述

4.数组元素的反转

//方法一:
		for(int i = 0;i < arr.length / 2;i++){
			String temp = arr[i];
			arr[i] = arr[arr.length - i -1];
			arr[arr.length - i -1] = temp;
		}
		
//方法二:
		for(int i = 0,j = arr.length - 1;i < j;i++,j--){
			String temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}

5.数组中指定元素的查找:

5.1 线性查找:

实现思路:通过遍历的方式,一个一个的数据进行比较、查找。
适用性:具有普遍适用性

5.2 二分法查找:

实现思路:每次比较中间值,折半的方式检索。
适用性:(前提:数组必须有序

6.数组的排序算法

排序:假设含有n个记录的序列为{R1,R2,...,Rn},其相应的关键字序列为{K1,K2,...,Kn}。将这些记录重新排序为{Ri1,Ri2,...,Rin},使得相应的关键字值满足条件Ki1<=Ki2<=...<=Kin,这样的一种操作称为排序。
通常来说,排序的目的是快速查找。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

理解:

1)衡量排序算法的优劣:

  • 时间复杂度:分析关键字的比较次数和记录的移动次数
  • 空间复杂度:分析排序算法中需要多少辅助内存
  • 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的。

2)排序的分类:内部排序 与 外部排序(需要借助于磁盘)

  • 内部排序:整个排序过程不需要借助于外部存储器(如磁盘等),所有排
    序操作都在内存中完成。
  • 外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排
    序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最
    常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。

3)不同排序算法的时间复杂度
在这里插入图片描述
4)手写冒泡排序

        int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};		
		//冒泡排序
		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]){
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}			
			}		
		}

5)手写快速排序

package com.atguigu.java;
/*
 * 快速排序
 * 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
 * 则分别对这两部分继续进行排序,直到整个序列有序。
 */
public class QuickSort {
	private static void swap(int[] data, int i, int j) {
		int temp = data[i];
		data[i] = data[j];
		data[j] = temp;
	}

	private static void subSort(int[] data, int start, int end) {
		if (start < end) {
			int base = data[start];
			int low = start;
			int high = end + 1;
			while (true) {
				while (low < end && data[++low] - base <= 0)
					;
				while (high > start && data[--high] - base >= 0)
					;
				if (low < high) {
					swap(data, low, high);
				} else {
					break;
				}
			}
			swap(data, start, high);
			
			subSort(data, start, high - 1);//递归调用
			subSort(data, high + 1, end);
		}
	}
	public static void quickSort(int[] data){
		subSort(data,0,data.length-1);
	}
	public static void main(String[] args) {
		int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
		System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
		quickSort(data);
		System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
	}
}

五、Arrays工具类的使用

1.理解

① 定义在java.util包下。
Arrays:提供了很多操作数组的方法。
java.util.Arrays类的sort()方法提供了数组元素排序功能
java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

2.使用

//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
		int[] arr1 = new int[]{1,2,3,4};
		int[] arr2 = new int[]{1,3,2,4};
		boolean isEquals = Arrays.equals(arr1, arr2);
		System.out.println(isEquals);
		
//2.String toString(int[] a):输出数组信息。
		System.out.println(Arrays.toString(arr1));
				
//3.void fill(int[] a,int val):将指定值填充到数组之中。
		Arrays.fill(arr1,10);
		System.out.println(Arrays.toString(arr1));
		
//4.void sort(int[] a):对数组进行排序。
		Arrays.sort(arr2);
		System.out.println(Arrays.toString(arr2));
		
//5.int binarySearch(int[] a,int key):对排序后的数组进行二分法检索指定的值。
		int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
		int index = Arrays.binarySearch(arr3, 210);
		if(index >= 0){
			System.out.println(index);
		}else{
			System.out.println("未找到");
		}

六、数组的常见异常

1.数组角标越界异常:ArrayIndexOutOfBoundsException

访问到了数组中的不存在的脚标时发生。

		int[] arr = new int[]{1,2,3,4,5};
		
		for(int i = 0;i <= arr.length;i++){
			System.out.println(arr[i]);
		}
		
		System.out.println(arr[-2]);
		
		System.out.println("hello");

2.空指针异常:NullPointerException

arr引用没有指向实体,却在操作实体中的元素时

情况一:
		int[] arr1 = new int[]{1,2,3};
		arr1 = null;
		System.out.println(arr1[0]);
		
情况二:
		int[][] arr2 = new int[4][]; //外层元素的初始化值为null
		System.out.println(arr2[0][0]);

情况三:
		String[] arr3 = new String[]{"AA","BB","CC"};
		arr3[0] = null;
		System.out.println(arr3[0].toString());

小知识:一旦程序出现异常,未处理时,就终止执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值