数组的分析

1、什么是数组

数组:数组是一种数据结构,在内存中是一块连续的空间,俗称为容器。

数组的特点:

①元素是连续存储的,每个元素都有自己的编号,通常称为下标。(因为有下标,故访问效率快)

②数组长度一旦确定,就不可更改。       

2、什么时候用数组

当我们需要同时管理一组相同数据类型的数据时,采用数组,比采用多个同类型的变量要简单的多。

案例:

public class TestArray {
    public static void main(String[] args) {
        //需求:存储5个同学的成绩
        int s1 = 89;
        int s2 = 96;
        int s3 = 76;
        int s4 = 98;
        int s5 = 60;

        //对它们进行数据管理:输出显示、找最高分、最低分、排序等 ==> 非常麻烦
        System.out.println("s1 = " + s1);
        System.out.println("s2 = " + s2);
        System.out.println("s3 = " + s3);
        System.out.println("s4 = " + s4);
        System.out.println("s5 = " + s5);
        int max = s1 > s2 ? s1 : s2;
        max = max > s3 ? max : s3;
        max = max > s4 ? max : s4;
        max = max > s5 ? max : s5;
        System.out.println("max = " + max);

        int[] score = {89, 96, 76, 98, 60};
        //输出5个分数,找最高分
        max = score[0];
        for (int i = 0; i < score.length; i++) {
            if(score[i]>max){
                max = score[i];
            }
            System.out.print(score[i]+"  ");
        }
        System.out.println("max = " + max);
    }
}

3、如何使用数组

3.1 声明数组的语法格式

元素的类型[] 数组名;

例如:

//存储一组商品的价格
double[] prices;

//存储一组同学的姓名
String[] names;

//存储26个英文字母
char[] letters;

3.2 数组的初始化

(1)静态初始化

在写代码时,直接确定了数组的元素。

数组名 = new 元素的类型[]{元素1,元素2,....};

当声明与静态初始化在一个语句时,可以简略成:

元素的类型[] 数组名 = {元素1,元素2,....};

案例:

public class TestArray {
    public static void main(String[] args) {
       // String[] names;
       // names = new String[]{"熊大","熊二","光头强","吉吉"};
        
        String[] names = {"熊大","熊二","光头强","吉吉"};
        
        System.out.println(names.length);//4
        for (int i = 0; i < names.length; i++) {
            System.out.println("第" + (i+1) +"个元素的值是:" + names[i]);
        }
    }
}
(2)动态初始化

在程序运行时,才确定元素的值。

数组名 = new 元素的类型[长度];
数组名[下标] = 值;

案例

import java.util.Scanner;

public class TestArray {
    public static void main(String[] args) {
        //从键盘输入5个同学的名字
        String[] names = new String[5];
        Scanner input = new Scanner(System.in);

        for(int i=0; i<names.length; i++) {
            System.out.print("请输入第"+(i+1)+"个同学的姓名:");
            names[i] = input.next();
        }

        //统一输出显示
        System.out.println("5个同学的名字如下:");
        for (int i = 0; i < names.length; i++) {
            System.out.print(names[i]+" ");
        }


        input.close();
    }
}

3.3 数组的遍历

使用for循环变量数组的场景是最多。当然,其实也可以使用while,或do-while。

for(int i=0; i<数组名.length; i++){
    //.....
}

3.4 数组的内存分析

  • 为什么打印数组名看不到元素?

    • 因为数组名里面存储了数组对象的首地址

  • 为什么需要用下标来访问元素?

    • 因为数组有多个元素,每一个元素只能通过编号进行区分

  • 为什么下标从0开始?

    • 访问第1个元素的时候,不需要跨过任何单元格

    • 访问第2个元素的时候,需要 首地址 + 1 * 每一个单元格的宽度 计算该元素的地址

    • 访问第3个元素的时候,需要 首地址 + 2 * 每一个单元格的宽度 计算该元素的地址

    • 下标相当于从首地址开始,需要跨过几个单元格来访问当前元素

元素的类型默认值
byte0
short0
int0
long0L
float0.0F
double0.0
char\u0000 或 编码值为0的字符
booleanfalse
String等引用数据类型null

3.5 两个数组or1个数组

4 二维数组

一维数组,即[],是用来存储一组数据的。例如:存储1个小组的学员信息

二维数组,即[][],是用来存储多组数据的 。例如:存储咱们班5个小组的学员信息

4.1 声明数组

元素的类型[][] 数组名;

4.2 数组的初始化

(1)静态初始化

元素的类型[][] 数组名 = {{第一组数据},{第二组数据},{第三组数据}};
public class ArrayPlus {
    public static void main(String[] args) {
        int[][] scores = {{89, 96, 76, 98, 60}, {99,100,98}, {7,8,9,6}};
        for (int i = 0; i < scores.length; i++) {//scores.length=3
//            System.out.println(scores[i]);//看到首地址
            //scores[i]也是一个一维数组
            /*
            i=0, scores[i].length=5
            i=1, scores[i].length=3
            i=2, scores[i].length=4
             */
            for (int j = 0; j < scores[i].length; j++) {
                System.out.print(scores[i][j]+" ");
                //[i]是行下标,定位行,或者 组
//                [j]是列下标,定位列,在组中第几个
            }
            System.out.println();
        }
    }
}

(2)动态初始化

  • 规则的矩阵

元素的类型[][] 数组名 = new 元素的类型[共有几行][每一行共有几个元素];
/*
1  2  3  4  5  第一组
6  7  8  9 10  第二组
11 12 13 14 15  第三组

每一组的元素个数相同
 */
public class ArrayPlus {
    public static void main(String[] args) {
        int[][] nums = new int[3][5];//3代表有3组,5代表每一组有5个元素
        int a = 1;
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                nums[i][j] = a;
                a++;
                System.out.print(nums[i][j]+"\t");
            }
            System.out.println();
        }
    }
}
  • 不规则矩阵

元素的类型[][] 数组名 = new 元素的类型[共有几行][]; //此时只确定了有几组,但是每一组有几个元素是待定
数组名[行下标] = new 元素的类型[这一组有几个元素];
/*
从键盘输入:
86,96,12
75,63
52
 */
public class ArrayPlusDemo3 {
    public static void main(String[] args) {
        int[][] nums = new int[3][];
        nums[0] = new int[6];//第1组有6个元素
        nums[1] = new int[5];//第2组有5个元素
        nums[2] = new int[7];//第3组有7个元素
        //如果是数组名后面[数字],就一定是下标,下标的范围[0, 长度-1]
        //如果是数据类型后面[数字],就一定是长度

        nums[0][0] = 86;
        nums[0][1] = 96;
        nums[0][2] = 12;

        nums[1][0] = 75;
        nums[1][1] = 63;

        nums[2][0] = 52;

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

4.3 遍历

for(int i=0; i<二维数组名.length; i++){
    for(int j=0; j<二维数组名[i].length; j++){
        //二维数组名[i][j]
    }
}

4.4 二维数组的内存分析

5 数组的基本算法

算法:解决问题的步骤

常见的数组算法:

(1)统计数组中元素满足xx条件的个数情况,例如:数组中偶数的个数、3的倍数的个数、素数的个数、完数的个数、水仙花的个数

(2)统计数组元素的总和、平均值

(3)查找数组元素的最大值、最小值

(4)对数组进行反转

(5)在数组中查找某个值是否存在

(6)数组的排序

。。。。。。

5.1 统计分析元素情况

案例:随机产生10个[0,100)的整数,然后统计这些随机数中偶数的个数、3的倍数各有多少个?

   //随机产生10个[0,100)的整数,然后统计这些随机数中偶数的个数、3的倍数各有多少个?
    public static void test(){
        int[] arr = new int[10];
        int oushu=0;
        int beishu=0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random()*100);
            if (arr[i] % 2 == 0){
                oushu++;
            }
            if (arr[i]%3==0){
                beishu++;
            }
            System.out.print(arr[i]+" ");
        }
        System.out.println("---------");
        System.out.println(oushu);
        System.out.println(beishu);
    }

5.2 统计总和、平均值

案例:随机产生5个[0,100)的整数,求它们的平均值

    //案例:随机产生5个[0,100)的整数,求它们的平均值
    public static void test(){
        int[] arr = new int[10];
        int sum=0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random()*100);
            sum+=arr[i];
            System.out.print(arr[i]+" ");
        }
        System.out.println();
        System.out.println("平均数:"+sum/ arr.length);
    }

5.3 找最大值、最小值

  //案例:随机产生5个[0,100)的整数,求它们的平均值

    //方法-
    public static void test() {
        int[] arr = {4, 5, 6, 11, 9};
        //第一步:假设第1个元素的值最大/最小
        int max = arr[0];
        int min = arr[0];
        //第二步:用后面的元素逐一与max比较,有比max大的,就修改max变量的值
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
            if (arr[i] < min) {
                min = arr[i];
            }
        }
        System.out.println("max = " + max);
        System.out.println("min = " + min);
    }

    //方法二
     public static void test2(){
        int[] arr = {4, 5, 6, 11, 9};
        //第一步:假设第1个元素的值最大/最小
        int max = 0;
        int min = 0;
        for (int i = 0; i < arr.length; i++) {
            if (i==0){
                max=arr[0];
                min=arr[0];
            }else if(arr[i] > max){
                max = arr[i];
            }else if(arr[i] < min){
                min = arr[i];
            }
        }
        System.out.println("max = " + max);
        System.out.println("min = " + min);
    }

5.4 找最大值及其下标位置

(1)元素不重复情况下

    //方法-
    public static void test() {
        int[] arr = {4,5,6,11,9};
        //需求:找出最大值是多少,并且确定它的下标位置
        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("max = " + max);
        System.out.println("index = " + index);
    }

    //方法二
     public static void test2(){
        int[] arr = {4, 5, 6, 11, 9};
        int index=0;
         for (int i = 0; i < arr.length; i++) {
             if (arr[i] > arr[index]){
                 index=i;
             }
         }
         System.out.println("max = " + arr[index]);
         System.out.println("index = " + index);
    }

(2)元素重复情况下

    //方法-
    //基础思路:
    //(1)先找出最大值
    //(2)在遍历一遍,看哪些元素和最大值一样,打印它们的下标
    public static void test() {
        int[] arr = {4, 5, 2, 6, 11, 9, 11};
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }
        System.out.println("max = " + max);
        System.out.println("max对应的下标有:");
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == max) {
                System.out.print("[" + i + "] ");
            }
        }
        System.out.println();
    }

    //方法二
    public static void test2() {
        int[] arr = {4, 5, 2, 6, 11, 9, 11};
        int max=arr[0];
        String str = "0";
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]>max){
                max=arr[i];
                str=i+"";
            }else if (arr[i] == max){
                str+=","+i;
            }
        }
        System.out.println("max = " + max);
        System.out.println("下标有:" + str);
    }

5.5 数组反转

    //方法-
    public static void test() {
        int[] arr = {5, 6, 8, 7, 21};
        //思路一:借助一个同等长度的数组(功能没问题,缺点就是需要同等大小的数组空间)
        int[] arrNew = new int[arr.length];
        //倒着复制元素
        for (int i = 0; i < arr.length; i++) {
            arrNew[arr.length-1-i]=arr[i];
        }
        arr = arrNew;
        //查看结果
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

    //方法二
    public static void test2() {
        //首尾对应位置交换法
        int[] arr = {4, 5, 2, 6, 11, 9, 11};
        int left =0;
        int right =arr.length-1;
        while (left<right){
            int temp = arr[left];
            arr[left] =arr[right];
            arr[right]=temp;
            left++;
            right--;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
    }

5.6 数组的查找之顺序查找

    //方法-
    public static void test() {
        int[] arr = {5, 6, 8, 7, 21};
        int target = 10;
        //判断target是不是数组中的一个元素
        boolean flag = false;//false在这里代表没找到
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                flag = true;//true代表找到了
                break;//停止查找
            }
        }

        if(flag){//if(flag==true) {
            System.out.println("找到了");
        }else{
            System.out.println("没找到");
        }
    }

    //方法二
    public static void test2() {
        //首尾对应位置交换法
        int[] arr = {4, 5, 2, 6, 11, 9,10, 11};
        int target = 10;

        //判断target是不是数组中的一个元素
        int index = -1;//index代表下标。 -1代表不存在
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                index = i;
                break;//停止查找
            }
        }

        if(index != -1){
            System.out.println("找到了,它的位置:" + index);
        }else{
            System.out.println("没找到");
        }
    }

如果如果数组是有序的,优化查找

顺序查找
    public static void test() {
        int[] arr = {5, 6, 8, 7, 21};
        int target = 10;
        int index = -1;
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] == target){
                index = i;
                break;
            }else if(arr[i] > target){
                break;
            }
        }
        System.out.println(index==-1?"不存在":"存在");
    }
二分查找
ublic static void test2() {
        int[] arr = {4, 5, 2, 6, 11, 9, 10, 11};
        int target = 10;
        int left = 0;
        int right = arr.length - 1;
        int index = -1;
        while (left < right) {
            int mid = left + (right - left) / 2; //防止left+right过大数据溢出
            if (arr[mid]>target){
                right = mid-1;
            } else if (arr[mid] < target) {
                left=mid+1;
            }else {
                index=mid;
                break;
            }
        }
        System.out.println(index == -1 ? "不存在" : "存在");
    }

5.7 冒泡排序

以从小到大排序过程为例,简单的描述冒泡排序的过程:

  • 每一轮,从头开始,通过==相邻元素比较==来实现排序。当前面的元素>后面的元素时,就交换它们。每一轮下来,可以保证本轮参与的所有元素中最大值会被交换到它应该在的位置。==n个元素经过n-1轮==之后,实现最终排序。

public static void test() {
    int[] arr = {5, 6, 8, 7, 21, 23, 1, 2, 8}; // 定义要排序的数组

    // 外层循环控制趟数,每趟将一个最大的数放到末尾
    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;
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值