数组
使用变量可以存储单个值,比如存5个人分数
int score1 = 99;
int score2 = 78;
int score3 = 69
int score4 = 83;
int score5 = 100;
这样虽然可以完成目标,但是繁琐。
1.初识数组
public class Array1{
public static void main(String[] args){
// 1.声明数组
int[] arr;
// 2.创建数组
arr = new int[5];
// 3.元素赋值
arr[0] = 99;
arr[1] = 78;
arr[2] = 69;
arr[3] = 83;
arr[4] = 100;
// 4.打印展示
for(int i = o; i < arr.length ; i++){
System.out.println(arr[i]);
}
}
}
2.使用数组
把大象放入冰箱步骤:
(1) 打开冰箱;
(2) 塞入大象;
(3) 关上冰箱!
2.1 数组创建
2.1.1 声明数组
# 格式如下:
dataType [] arrayNmae;
int[] arr1;
double[] arr2;
String[] arr3;
char[] arr4;
......
2.1.2 数组基本元素
- 数组数据类型声明
dataType
- 数组变量名
arrName
- 数组长度
[size]
arrName.length
- 数组下标索引
从零开始
2.1.3 创建数组
一. 静态初始化
#格式如下:
arrName = new dataType[size];
arr1 = new int[5];
arr2 = new double[10];
arr3 = new String[10];
arr4 = new char[10];
以上操作两步骤:
一.使用dataType[size]创建了一个数组
二.把新创建的数组引用赋值给arrName
以上步骤可以简化如下
dataType[] arrName = new dataType[size];
可以再进一步简化:
dataType[] arrName = {val1, val2 ... valk};
此时虽然没有声明数组的长度,但是JVM可以自动推断合适长度
二.动态初始化
语法如下:
// 声明数组, 指定长度
数组名 = new 元素数据类型[长度]
//循环动态赋值
for(int i = 0; i<长度; i++){
数组名[i] = 值;
}
2.2 数组操作/分析
2.2.1 遍历操作
语法格式
for(int i = 0; i<长度; i++){
// 赋值操作
数组[下标] = 值;
//或者显示
System.out.println(i);
//或者其他操作
...
}
2.2.2 简单数组分析
int[] arr;
arr = new int[5];
arr[0] = 1;
arr[1] = 3;
arr[2] = 5;
arr[3] = 7;
arr[4] = 9;
(1) 首先在栈上生成变量arr
(2) arr变量指向堆上面一块区域;这块区域分配有5个大小相同房子。此时, arr变量指向的是这块区域首地址;
(3) 通过下标索引进行赋值,从而一一排列
2.2.3 动态数组内存分析
int[] arr = new int[5];
for(int i=0; i<arr.length; i++){
arr[i] = i+1;
}
3.数组算法
3.1 找最值
思路:
(1) 先找一个基准值
(2) 然后用基准值依次跟其他值比较
int[] arr = {4, 8, 9, 3, 7, 1};
// 假设基准值为 arr[0]
int base = arr[0];
for(int i = 1; i<arr.length; i++){
if(base > arr[i]){
base = arr[i];
}
}
演变 找最值及其下标
思路1:
(1) 先找一个基准值
(2) 然后用基准值依次跟其他值比较
(3) 需要申请两个变量保存最值和下标
int[] arr = {4, 8, 9, 3, 7, 1};
// 假设基准值为 arr[0]
int base = arr[0];
int minIndex = 0;
for(int i = 1; i<arr.length; i++){
if(base > arr[i]){
base = arr[i];
minIndex = i;
}
}
思路2:
一个变量完成
int[] arr = {4, 8, 9, 3, 7, 1};
int maxIndex = 0;
for(int i=1; i<arr.length; i++){
if(arr[i] < arr[maxIndex]){
maxIndex = i;
}
}
System.out.println("最大值:" + arr[maxIndex]);
3.2 找最值及其所有下标
思路:
(1) 先找一个基准值
(2) 然后用基准值依次跟其他值比较
(3) 找到结果和其他对比是否相同
int[] arr = {1, 3, 5, 7, 1, 9, 1};
int result = 0;
for(int i = 1; i<arr.length; i++){
if(arr[result] > arr[i]){
result = i;
}
}
for(int i = 0; i<arr.length; i++){
if(arr[result] == arr[i]){
System.out.print(i + "/t/t");
}
}
3.2 数组统计、求和、平均值操作
3.2.1 求和操作
遍历全部元素,依次累加
int[] arr1 = {2, 5, 8, 12, 9};
int sum = 0;
for(int i = 0; i<arr1.length; i++){
sum += arr1[i];
}
System.out.println(sum);
3.2.2 求均值
int[] arr2 = {2, 5, 8, 12, 9};
int sum = 0;
double num = 0;
double avg ;
for(int i = 0; i<arr2.length; i++){
sum += arr2[i];
num++;
avg = sum / num;
}
System.out.println(avg );
3.2.3 求奇数个数
int[] arr2 = {2, 5, 8, 12, 9};
int sum = 0;
int num = 0;
for(int i = 0; i<arr2.length; i++){
if(arr2[i] % 2 != 0){
num++;
}
}
System.out.println(num);
3.3 数组反转操作
方法一 : 借助新数组进行置换
通过首尾交换位置
int[] arr3 = {1,2,3,4,5,6,7,8,9};
// 1.创建新数组
int[] newArray = new int[arr3.lenght];
// 2.元素复制
int len = arr3.length;
for(int i = 0; i<arr3.length; i++){
newArray[i] = arr3[len - 1 - i];
}
// 3.重新指向新的数组
arr3 = newArray;
方法二: 原地反转
int[] arr3 = {1,2,3,4,5,6,7,8,9};
// 1.计算交换次数 arr3.length / 2
// 2.借助第三方变量交换
int temp = 0;
for(int i = 0; i<arr3.length / 2; i++){
temp = arr3[i];
arr3[i] = arr3[arr3.length - 1 - i];
arr3[arr3.length - 1 - i] = temp;
}
3.4 复制
应用:
-
扩容
-
备份
3.截取
扩容例
int[] arr = {1,2,3,4,5,6,7,8,9};
//如果要把arr数组扩容,增加1个位置
//(1)先创建一个新数组,它的长度 = 旧数组的长度+1
int[] newArr = new int[arr.length + 1];
//(2)复制元素
//注意:i<arr.length 因位arr比newArr短,避免下标越界
for(int i=0; i<arr.length; i++){
newArr[i] = arr[i];
}
//(3)把新元素添加到newArr的最后
newArr[newArr.length-1] = 新值;
//(4)如果下面继续使用arr,可以让arr指向新数组
arr = newArr;
//(4)遍历显示
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
备份例
int[] arr = {1,2,3,4,5,6,7,8,9};
//1、创建一个长度和原来的数组一样的新数组
int[] newArr = new int[arr.length];
//2、复制元素
for(int i=0; i<arr.length; i++){
newArr[i] = arr[i];
}
//3、遍历显示
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
截取例
int[] arr = {1,2,3,4,5,6,7,8,9};
int start = 2;
int end = 5;
//1、创建一个新数组,新数组的长度 = end-start + 1;
int[] newArr = new int[end-start+1];
//2、赋值元素
for(int i=0; i<newArr.length; i++){
newArr[i] = arr[start + i];
}
//3、遍历显示
for(int i=0; i<newArr.length; i++){
System.out.println(newArr[i]);
}
3.5 查找
- 顺序查找
对数组没要求
例子:
int[] arr4 = {4, 5, 9, 3, 6, 8, 12}
int value = 6;
int index = -1;
for(int i = 0; i<arr4.length; i++){
if(arr4[i] == value){
index = i;
}
}
if(index != -1){
System.out.println("value的index是: " + index);
}else{
System.out.println("404 Not found!")
}
- 二分查找
对数组要求: 必须是按序排列
int[] arr5 = {1, 3, 5, 7, 9. 11, 13, 15,17};
int value = 13;
int index = -1;
int left = 0;
int right = arr5.length - 1;
int mid = (left + right) / 2;
while(left < right){
if(value == arr5[mid]){
index = mid;
break;
}else if(value > arr[mid]){
left = mid + 1;
}else{
right = mid - 1;
}
}
if(index != -1){
System.out.println("value的index是: " + index);
}else{
System.out.println("404 Not found!");
}
for 循环改写
int[] arr5 = {1,3,5,7,11,13,15,17,19};
int value = 13;
int index = -1;
for(int left = 0, right = arr5.length - 1, mid = (right + left) / 2; left <= right; mid = (right + left) / 2 ){
if(value == arr5[mid]){
index = mid;
break;
}else if( value > arr5[mid]){
left += 1;
}else if(value < arr[mid]){
right -= 1;
}
}
if(index == -1){
System.out.println("404 Not found!");
}else{
System.out.println("value的index是: " + index);
}
3.6 排序
- 冒泡排序
例子
int[] arr = {5, 8, 4, 2, 1}
/*
第1轮,i=1,从左到右两两比较,arr[0]与arr[1]。。。。。arr[3]与arr[4]
第2轮,i=2,从左到右两两比较,arr[0]与arr[1]。。。。。arr[2]与arr[3]
...
arr[j]与arr[j+1]比较
找两个关键点:(1)j的起始值:0(2)找j的终止值,依次是3,2,1,0,得出j<arr.length-i
*/
for(int i = 0; i<arr.length; i++){
//两两比较
//从小到大,说明前面的比后面的大,就交换
for(int j = 1; j<arr.length - i; j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
- 选择排序
int[] arr = {3,2,6,1,8};
for(int i=1; i<arr.length; i++){//外循环的次数 = 轮数 = 数组的长度-1
//(1)找出本轮未排序元素中的最值
/*
未排序元素:
第1轮:i=1,未排序,[0,4]
第2轮:i=2,未排序,[1,4]
...
每一轮未排序元素的起始下标:0,1,2,3,正好是i-1的
未排序的后面的元素依次:
第1轮:[1,4] j=1,2,3,4
第2轮:[2,4] j=2,3,4
第3轮:[3,4] j=3,4
第4轮:[4,4] j=4
j的起点是i,终点都是4
*/
int max = arr[i-1];
int index = i-1;
for(int j=i; j<arr.length; j++){
if(arr[j] > max){
max = arr[j];
index = j;
}
}
//(2)如果这个最值没有在它应该在的位置,就与这个位置的元素交换
/*
第1轮,最大值应该在[0]
第2轮,最大值应该在[1]
第3轮,最大值应该在[2]
第4轮,最大值应该在[3]
正好是i-1的值
*/
if(index != i-1){
//交换arr[i-1]与arr[index]
int temp = arr[i-1];
arr[i-1] = arr[index];
arr[index] = temp;
}
}
//显示结果
for(int i=0; i<arr.length; i++){
System.out.print(arr[i]);
}
4.二维数组
二维数组的标记:[][]
4.1 相关表示方式
(1)二维数组的长度/行数:
二维数组名.length
(2)二维数组的其中一行:
二维数组名[行下标]
行下标的范围:[0, 二维数组名.length-1]
(3)每一行的列数:
二维数组名[行下标].length
因为二维数组的每一行是一个一维数组
(4)每一个元素
二维数组名[行下标][列下标]
4.2二维数组的声明初始化
1、二维数组的声明
//推荐
元素的数据类型[][] 二维数组的名称;
2、二维数组的初始化
(1)静态初始化
二维数组名 = new 元素的数据类型[][]{
{第一行的值列表},
{第二行的值列表},
...
{第n行的值列表}
};
//如果声明与静态初始化一起完成
元素的数据类型[][] 二维数组的名称 = {
{第一行的值列表},
{第二行的值列表},
...
{第n行的值列表}
};
(2)动态初始化(不规则:每一行的列数可能不一样)
//(1)先确定总行数
二维数组名 = new 元素的数据类型[总行数][];
//(2)再确定每一行的列数
二维数组名[行下标] = new 元素的数据类型[该行的总列数];
//(3)再为元素赋值
二维数组名[行下标][列下标] = 值;
3.二维数组的遍历
for(int i=0; i<二维数组名.length; i++){
for(int j=0; j<二维数组名[i].length; j++){
System.out.print(二维数组名[i][j]);
}
System.out.println();
}