数组

使用变量可以存储单个值,比如存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 数组基本元素

  1. 数组数据类型声明

dataType

  1. 数组变量名

arrName

  1. 数组长度

[size]
arrName.length

  1. 数组下标索引

从零开始

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 复制

应用:

  1. 扩容

  2. 备份

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 查找

  1. 顺序查找

对数组没要求

例子:

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!")
}
  1. 二分查找

对数组要求: 必须是按序排列

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 排序

  1. 冒泡排序

例子

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;            
            }
}
}
  1. 选择排序
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();
}