JAVA基础——数组、排序和查找(韩顺平P155-P191)

目录

一、基础概念

二、数组的使用

三、相关案例、应用

1、数组的翻转

2、数组的添加(动态扩容)

3、排序(冒泡排序)

4、查找

四、多维数组:二维数组

1、概念和定义

2、二维数组的使用

3、案例——杨辉三角


一、基础概念

为什么需要数组?比如说已知6只鸡的体重,要求平均体重。

传统方法就是定义6个变量,再累加/6。(如果有600只鸡,那要定义太多变量),所以引入了数组

  • 定义:数组也是一种数据类型,是引用类型数组可以存放多个同一类型的数据。(数组就是一组数据)。
  • 还是鸡体重的例子。下面代码是用数组实现,可以看到方便很多,当增加一只鸡的时候只需要在数组里面增加一个数就行,不用再重新定义一个变量了。
public class Array01 {
    public static void main(String[] args){
        // 先定义一个数组.double[]表示double类型的数组
        double[] hens = {3,5,1,3.4,2,50};        
        double sum = 0;  // 遍历数组,得到所有元素的和
        for(it i=0; i < hens.length; i++){
            System.out.println("第"+(i+1)+"元素的值为"+ hens[i]); // 可以通过下标来访问数组的元素,下标是从0开始的
            sum+=hens[i];  // 累加每个元素
        }
        System.out.println("平均体重为:"+ (sum / hens.length));
    }
}

二、数组的使用

  • 数组的定义:
    • 方法一:动态初始化。数据类型[ ] 数组名 = new 数据类型[大小]; (或者数据类型 数组名[ ]也行)
      • int a[] = new int[5];  (内存中有一个变量名a,指向一个数组5个框框,初始值为0)
      • 也是可以先申明 int a[] 或者 int[] a 这时候内存中只有一个变量名,还没有分配空间,指向什么; 再创建数组 a = new int[10]  这时候才分配空间;
    • 方法三:静态初始化。直接:数据类型 数组名[] = {元素值, 元素值, ……}
      • int a[] = {2,4,5,6,7}
  • 数组的引用
    • 数组名[下标/索引]:比如访问第三个数:a[2]  下标从0开始
  • 小细节
    • 数组里面必须放相同类型的。但是低精度可以赋给高精度的(自动类型转换,可以兼容)
    • 数组里面不仅可以放基本数据类型,还能放引用类型(对象)
    • 数组创建后,如果没有直接赋值,会给初始值。
      • int默认为0,double默认0.0,boolean默认false,String默认null。
    • 数组下标从0开始。引用时必须在范围内(不然会报错越界)
    • 数组是引用类型,本质是对象object(下章会讲)。
public class Array02 {
    public static void main(String[] args){
        // 练习1::把A-Z放进数组
        char[] chars = new[26];
        for(int i=0; i< chars.length; i++){
            chars[i] = (char)('A' + i); // 'A'+1=65+1=66 对应B
            // 注意需要强制转换。 因为('A' + i)是int类型,int不能直接转换为char
        }
        // 练习2:求一个数组的最大值及其下标
        int[] arr = {4,-1,9,10,23};
        int max = arr[0]; // 先假定第一个元素就是最大值
        int maxIndex = 0;
        for(int j=1; j< arr.length; j++){
            if(arr[j]>max){   // 如果当前值大于max,就更新
                max = arr[j];
                maxIndex = j;
            }
        }
        System.out println("第"+j+"个元素最大,值为:"+max);
    }
  • 数组的赋值机制
    • 基本数据类型赋值,这个值就只是具体的数据,而且互相不影响。
      • int n1=2; int n2=n1;  然后再n2=3;这样n1还是2. (值拷贝:n2只是得到了n1的值
    • 数组默认是引用拷贝,赋的是地址,引用传递。即共同作用于一个地址空间,共同修改
      • int[] arr1 = {1,2,3}; int[] arr2 = arr1;  这是arr2的变化会影响到arr1
      • 比如arr2[0] = 10; . 这是arr1变成了{10,2,3}。
      • 如果就是只想拷贝值,想要空间独立。就创建新数组arr2,保证和arr1一样大。然后循环遍历一个个值赋进来,arr2[i] = arr1[i].
    • jvm的内存分为栈、堆、方法区。int[] arrr1 = {1,2,3}之后,会在栈里面,变量名a指向一个地址,然后在堆里面,对应的地址产生内存空间,里面3个小区,分别记录了arr[0],arr[1],arr[2]的值。int[] arr2 = arr1; 就相当于,在栈里面把地址复制过来,这个地址在堆里面指向同样的空间。即arr1[0]和arr2[0]访问的是同一个小空间。arr2[0] = 10;之后,是改的空间里面的值。所以堆里面的这个空间已经改变了。

三、相关案例、应用

1、数组的翻转

// 翻转数组
public class Array02 {
    public static void main(String[] args){
        int[] arr = {4,-1,9,10,23,25};
        // 也就是把arr[0]和arr[5]交换、arr[1]和arr[4]交换、arr[2]和arr[3]交换
        // 交换了3次 arr.length/2。
        // 第i次交换,把arr[i]和arr[arr,length-1-i]进行交换
        for(int i=0; i< arr.length/2; i++){
            int temp = arr[arr.length-1-i];  //临时存放
            arr[arr.length-1-i] = arr[i];
            arr[i] = temp;
        }
    }
    // 或者也可以另外创建一个arr2,然后逆序遍历arr1,一个个赋值
    // for(int i=arr1.length,j=0;i>=0;i--,j++){arr2[j]=arr1[i]}
}

2、数组的添加(动态扩容)

假设原始数组使用静态分配,增加元素直接放在后面。然后用户可以通过输入y/n来决定是否继续添加。(代码如下,数组缩减,也是同样的道理。)

import java.util.Scanner;
public class Array03 {
    public static void main(String[] args){
        Scanner myScanner = new Scanner(System.in);
        int[] arr = {1,2,3}; // 原始数组
        do{  // 至少扩容一次
            int[] arrnew = new int[arr.length+1]; //必须再定义一个数组
            for(int i=0; i<arr.length; i++){
                arrnew[i] = arr[i];  // 依次遍历赋值
            }
            System.out println("请输入你要添加的元素:");
            int addNum = myScanner.nextInt();
            // 然后增加新元素
            arr[arrnew.length-1] = addNum; // 增加的数字
            arr = arrnew;  //把arr指向新数组,原来这个可以销毁掉了
            System.out println("是否要继续添加:");
            char answer = myScanner.next.charAt(0); // 输入y或者n
            if(answer=='n'){
                break;
            }
        }while(true);       
    }
}

3、排序(冒泡排序)

  • 就是将多个数组,按照指定的顺序进行排列。有两种排序。

        1、内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序。(包括交换式排序法、选择式排序法、插入式排序法)

        2、外部排序法:数据量过大,无法全部加载到内存中,需要借助外部存储进行排序(包括合并排序法和直接排序法)(大数据的应用场景会用到,一块一块排序)。

  • 冒泡排序(bubble sorting):依次比较相邻元素的值,若发现逆序则交换(使值较大的元素逐渐移动到后部)
  • 如下,一共有5个元素,经过了4轮排序(外层循环),每一轮排序可以确定一个末尾数的位置。每轮比较时,如果前面的数大于后面的,就交换。每一轮比较的次数逐渐减少(4321)

public class BubbleSort {
    public static void main(String[] args){
        int[] arr = {24,69,80,57,13};
        for(int i=0; i< arr.length-1; i++){ // 进行len-1=4轮比较
            for(int j=0; j< arr.length-i; j++){  // 第i轮进行len-i次比较
                if(arr[j] > arr[j+1]){ // 如果前面的数大于后面的数
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;  // 交换
            }
        }
        }
    }
}

4、查找

在java中有两种查找:顺序查找、二分查找(后面讲)。

有一个数组,从键盘中任意输入一个值,判断数组中是否有这个数,返回下标值。

import java.util.Scanner;
public class SequenceSearch {
    public static void main(String[] args){
        int[] arr = {1,3,5,2,6};
        Scanner myScanner = new Scanner(System.in);
        System.out println("请输入一个值");
        int num = myScanner.nextInt();
        int index = -1;  //想要看看有没有找到,可以用这个index来验证一下
        for(int i=0;i<arr.length;i++){
            if(num==arr[i]){
                System.out println("下标为:"+i);
                index = i;
                break;
            }
        }
        if(index==-1){
            System.out println("没有找到");
        }
    }
}

四、多维数组:二维数组

1、概念和定义

应用场景:比如说要开发五子棋盘,就需要二维的。

可以理解为:二维数组的每个元素都是一个一维数组(数组里面套数组)

public class TwoDimensionalArray {
    public static void main(String[] args){
        int[][] arr = {{1,3,5,2,6},{1,3,5,2,6},
                       {1,3,5,2,6},{1,3,5,2,6}};  // 4*5的
        for(int i = 0; i< arr.length; i++){  // 相当于对第一个维度的遍历,4个
            for(int j=0; j< arr[i].length; j++){  // 得到具体第二个维度下的元素个数
                System.out print(arr[i][j]+"\t");
            }
            System.out println();  // 换个行
        }
    }
}

2、二维数组的使用

  • 定义:类型名[][] 数组名 = new 类型[大小][大小]    比如int a[][] = new int[2][3]; 同样也可以先申明再开辟空间。( int[] y[] = new int[2][3]; 也可以)
    • int[] x,y[];  这样x是一个一维数组,y是一个二维数组。
    • 内存:如果是int a[][] = new int[2][3]; 会先在栈里面指向一个地址,然后地址指向堆里面一个空间(包含两个小空间,也是放的地址),然后每个地址再指向一个新空间(包含3个小空间,才是放的具体的值。)

  • 在java中,允许二维数组下的每个一维数组元素数量不同。即列数不确定的情况。
public class TwoDimensionalArray {
    public static void main(String[] args){
        // int[][] arr = {{1},{2,2},{3,3,3}};想实现这样的效果
        int[][] arr = new int[3][];  // 列数不确定,只确定了一维数组的个数
        for(int i=0; i < arr.length; i++){  //有3个一维数组
            arr[i] = new int[i+1]; // 对每个一维数组开辟空间
            for(int j=0; j < arr[i].length; j++){ // 赋值
                arr[i][j] = i+1;
            }
        }
    }
}

3、案例——杨辉三角

用二维数组打印一个10行的杨辉三角。(可以解决二项式的问题)。

public class YangHui {
    public static void main(String[] args){
        int[][] arr = new int[10][];
        for(int i=0; i < arr.length; i++){
            arr[i] = new int[i+1];
            for(int j=0; j < arr.length; j++){
                if(j==0 || j==arr.length-1){
                    arr[i][j]=1;   // 每行头尾为1
                }else{
                    arr[i][j] = arr[i-1][j-1] + arr[i-1][j]; // 中间的元素等于上一行的两个元素相加
                }
            }
        }
        // 然后再两层循环遍历输出
    }
}

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值