【Java基础】数组、排序和查找

1、数组

1-1、概念

  • 是一种数据结构,根据下标来访问其中蕴含的数据,用于存储多个相同类型的变量,而不用定义多个变量

1-2、定义

1-2-1、动态初始化

定义的同时分配空间 如:int[ ] arr = new int[5];   一条语句
定义后再根据条件需要分配空间 如:int[ ] arr;
arr = new int[6];   两条语句

1-2-2、静态初始化

创建的同时赋值 如:int[ ] arr = new int[ ]{1,2,3,4,5};
其简化写法:int[ ] arr = {1,2,3,4,5};
最后一个值后面允许有逗号,方便为数组增加值

1-2-3、长度为0

int[ ] arr = new int[0];
int[ ] arr = new int[ ]{ };
注意长度为0和null意义不相同

1-2、赋值机制

问题:当将一个初始化好的数组A给另一个数组B保存时,修改数组A的值仍然会修改B的值,而基本数据类型则不会出现这种情况

基本数据类型的数据直接在栈中开辟存储数据,而数组存储是通过地址值,地址值指向真正的数据的方式来存储,将arr1给arr2保存两个数组都是存储同一个地址,自然操作的是同一个数据。
如图示:
在这里插入图片描述

1-3、数组相关操作

1-3-1、拷贝

  • 需要创建一个新的数组逐个元素赋值,而不是直接用一个数组变量接收
public class Test {
    public static void main(String[] args) {
        int[] arr1 = {1,2,3};
        int[] arr2 = arr1;//1、赋的是地址,并不是真正的拷贝
        //2、真正的拷贝需要重写创建一个数据逐个元素赋值
        int[] arr3 = new int[3];
        for (int i = 0; i < 3; i++) {
            arr3[i] = arr1[i];
        }
        //3、测试  arr1不变 arr3的值改变
        arr3[2] =100;
        System.out.println(Arrays.toString(arr1));
        System.out.println(Arrays.toString(arr3));
    }
}

1-3-2、翻转

public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        //思路一:两个下标,首位元素依次交换
        int i,j,temp;
        for (i = 0,j=arr.length-1; i <= j; i++,j--) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        System.out.println(Arrays.toString(arr));

        //思路二:再创建个数组,新数组用于保存逆序后的数据
        //然后再让旧数组指向新数组(拷贝),完成旧数组的逆序
        int[] old_arr = {1,2,3,4,5,6};
        int[] new_arr = new int[old_arr.length];
        int k,p;
        for (k = 0,p =old_arr.length-1; p>=0; k++,p--) {
            new_arr[p] = old_arr[k];
        }
        //让旧数组指向逆序后的数组
        old_arr = new_arr;
        System.out.println(Arrays.toString(old_arr));
    }
}

1-3-3、扩容与缩减

  • 创建新数组增加原先长度,缩减同理
  • 由用户指定决定是否继续创建
public class Test {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        Scanner s = new Scanner(System.in);
        int addnum;
        do{
            int[] arr2 =  new int[arr.length+1];
            for (int i = 0; i < arr.length; i++) {
                arr2[i] = arr[i];
            }
            System.out.println("请输入要添加的数据");
            arr2[arr.length] = s.nextInt();
            arr = arr2;//改变指向旧数组
            System.out.println("是否继续输入(Y/N)");
            //charAt(int n)用于检索字符串特定下标下的字符
            if( s.next().charAt(0)=='N'){
                break;
            }
        }while (true);
        System.out.println(Arrays.toString(arr));
    }
}

2、排序

1、冒泡排序

  • 类似两个指针分别指向第一、二元素,比较之后都向后移动,继续相邻间两两比较,由此可确定一个最大值。如果想确定第二大的值则需从头开始比较,但不再需比较最后一个已经确定是最大的元素
public class Test {
    public static void main(String[] args) {
        int[] arr = {24,12,37,58,47};
        int i,j,temp;
        //数组长度为5,则需进行四次排序,每次排序进行相邻元素间的两两比较
        for(i=0;i<arr.length-1;i++){
            //内循环-1是因为下标从0开始,
            //-i是因为每一次外循环结束都确定了一个最大值,不再需要比较
            for(j=0;j<arr.length-i-1;j++){
                if(arr[j]>arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
        /**
         * {24,12,37,58,47,10}
         * 第一轮排序,
         *      第一次比较:{12,24,37,58,47}  第一个元素和第二个比 交换位置
         *      第二次比较:{12,24,37,58,47}  第二个元素和第三个比 位置不变
         *      第三次比较:{12,24,37,58,47}  第三个元素和第四个比 位置不变
         *      第四次比较:{12,24,37,47,58}  第四个元素和第五个比 交换位置
         * 结果:将最大数放在最后一位
         *
         * 第二轮排序:
         *      第一次比较:{12,24,37,47,58}  第一个元素和第二个比 位置不变
         *      第二次比较:{12,24,37,47,58}  第一个元素和第二个比 位置不变
         *      第三次比较:{12,24,37,47,58}  第一个元素和第二个比 位置不变
         * 结果:将第二大的数放在倒数第二位
         * 注意:最后一个元素已经由第一轮排序决定,不再需要参与比较
         *
         *依次类推
         */
    }
}

3、查找

3-1、顺序查找

  • 遍历下标 一个个进行if判断判断数组中是否存在

3-2、二分查找

4、二维数组

4-1、定义

动态初始化1: int[][] arr = new int[2][3];
动态初始化2: int[][] arr;
        arr = new int[2][3];
静态初始化:  int[][] arr = { {1,2,3},{4,5,6} };

4-2、内存存在形式

  • 一开始和一维数组一样在栈中的存储的是地址,但二位数组变量arr存储的地址指向的是一个存储地址的数组,其中每个元素地址都指向一个数组,此时数组里存储的才是真正的元素
    由图可知和一维数组相比,二维的嵌套都发生在堆中
    在这里插入图片描述

4-3、使用案例

4-3-1、动态创建二维数组

public class Test {
    public static void main(String[] args) {
        /** 动态创建二位数组
         * 1
         * 1 2
         * 1 2 3
         */
        int[][] arr = new int[3][];
        //动态创建每个一维数组
        for (int i = 0; i < 3; i++) {
            //每次都要创建一维数组作为二维的元素
            int[] a = new int[i+1];
            //为一维数组赋值
            for (int j = 0; j < i+1; j++) {
                a[j] = j+1;
            }
            //让二位数组指向生成好的新数组
            arr[i] = a;
        }
        //打印,由于二维数组内的每个一维数组大小不一致,
        //故内循环打印一维数组元素的终止条件是变量
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j <= i; j++) {
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }
}

4-3-2、杨辉三角

  • 先确定二维数组的行数,再具体为每一行的一维数组开辟空间,再为其赋值
  • 杨辉三角特点:每一行的首尾元素相同,其余元素为同列上一个和其前一个之和
public class Test {
    public static void main(String[] args) {
        /** 动态创建二位数组创建
         * 1
         * 1 1
         * 1 2 1
         * 1 3 3 1
         * 1 4 6 4 1
         * ...
         */
        System.out.println("请输入要生成行数");
        Scanner s = new Scanner(System.in);
        int line = s.nextInt();
        //先由用户输入确定要生成几个一维数组
        int arr[][] = new int[line][];
        int i,j;
        for (i = 0; i < arr.length; i++){
            //再为二维数组中的一维数组开辟空间
            arr[i]= new int[i+1];
            //为一维数组赋值
            for (j = 0; j < arr[i].length; j++) {
                //每一行的首尾元素都是1
                if(j==0 || j==arr[i].length-1){
                    arr[i][0] = arr[i][j] =1;
                }else {
                    //杨辉三角规律
                    arr[i][j] = arr[i-1][j] + arr[i-1][j-1];
                }
            }
        }

        //打印 外循环是二维数组长度,内循环是一维数组长度
        for (i = 0; i < arr.length; i++) {
            for (j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }

    }
}

4-4、练习

4-4-1、数组的声明

在这里插入图片描述坑点在int[] y[],也是二维数组的定义方式 答案:be

4-4-2、升序数组插入仍是升序

  • 先定位,后扩容
  • 扩容涉及快慢指针的知识
	//[10,12,45,90] 添加任意数据仍然是升序
    public static void test(){
        //扩容+定位
        int[] arr = {10,12,45,90};//27
        System.out.println("请输入要插入的数字:");
        Scanner s = new Scanner(System.in);
        int num = s.nextInt();
        int i,j,flag=0,index=0;
        //像得到要插入的位置
        for(i=0;i<arr.length;i++){
            if(arr[i]<=num){
                index = i+1;//升序数组,位置在其后方
            }
        }
        //扩容,利用快慢指针,当遇到要插入的位置时,让arr的指针j慢一拍
        //以保证其能指向正确的数据
        //
        //10 12     45 90
        int[] arrNew = new int[arr.length+1];
        for(i=0,j=0;i<arrNew.length;i++){
            //不是插入位置,正常添加数据,
            //旧数组的指针j和新数组的指针i均正常自增
            if(i!=index){
                arrNew[i] =arr[j];
                j++;
            }else{//需要插入数,此时插入数据,
                  // 新数组指针正常移动但旧数组指针不动
                  //例如要插入的数据是5,则一开始会直接到此
                  //形成【5,0,0,0,0】 ,后续再正常赋值
                arrNew[i] = num;
            }
        }
        System.out.println(Arrays.toString(arrNew));
    }

编排格式

文字大小
红色
蓝色
橙色
紫色
绿色
 空格

表格第一行:背景颜色、对齐
表格第二行:变大变颜色变高

表格的第三行:居中 第二列
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值