Day10——数组

Day10——数组

1、数组

1. 数组概述:

数组是,相同类型数据的有序集合。

通常使用数组下标来区分或指定每一个数组元素,数组下标从0开始(假设一个数组有4个数,那么数组下标就是0、1、2、3)。

使用数组避免了定义多个变量的麻烦,并且会让程序变的简单。

2. 数组的声明、创建

声明、创建数组格式:

声明:
dataType[] array;  //声明一个dataType类型的数组,名称为array
dataType array[];  //与1同义,常用于C、C++语言
创建:
array = new dataType[length];//创建array数组长度为length
声明+创建:
dataType[] array = new dataType[length];
    //声明并创建一个dataType类型的数组,名称为array,长度为length

【例1】:

声明:
int[] nums;//声明整型数组,亦可写作  int nums[];    后者为C、C++写法
创建:
nums = new int[10];//创建长度为10的整型数组(即数组元素有十个)
声明+创建:
int[] nums = new int[10];// 声明 + 创建一个长度为10的整型数组

获取数组长度:数组名.length

数组的元素是通过索引访问的。数组索引从 0 开始,所以索引值从 0 到 (数组名.length-1)。

3. 内存分析

Java内存分析:

在这里插入图片描述

  1. 声明数组,数组会被放在中,此时数组并没有被真正的创建
  2. 创建数组时,数组被放入堆中,此时数组元素还未进行初始化,基本数据类型的数组元素默认值为0,String数组默值认为null
  • 三种初始化

    1. 静态初始化:

除了用new关键字来创建数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

int[] a = {1,2,3};

2. 动态初始化:   即声明数组后,用new创建数组,并维数组赋值的操作(分开进行)。

3. 数组的默认初始化:

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实 例变量同样的方式被隐式初始化。基本数据类型的数组元素默认值为0,String数组默值认为null。

 ### 数组的使用
  1. For-Each循环:

    JDK 1.5 引进了一种新的循环类型,被称为 For-Each 循环或者加强型循环,它能在不使用下标的情况下 遍历数组。

    语法格式:

    type array = new type[length];
    //声明并创建一个type型,array数组,长度为length
    for(type element: array){
          
          //没有数组下标
    	System.out.println(element);//输出element数组的元素
    }
    

    在IDEA中【缩写】nums.for = for (type i : nums){}

    其中,nums为数组名,type为数组类型,i为任意名称、代指数组中元素。

  2. 数组作为方法的参数:

    【例2】写一个输出数组的方法printArray

    public static void printArray(int[] arrays){
          
          
        for( i = 0; i < arrays.length; i++ ){
          
          
            System.out.println(arrays[i]+" ")
        }
    }
    

    或者写做:

    public static void printArray(int[] arrays){
          
          
        for(int i: array){
          
          
            System.out.println(i);
        }
    }
    
  3. 数组作为返回值:

    【例3】写一个方法反转数组,并让数组作为返回值

    public static void main(String[] args) {
          
          
        int[] arrays = {
          
          1,2,3,4,5};
        int[] a = printRe(arrays);
        //5.反转arrays数组,赋值给a数组
        for(int i: a){
          
          
            System.out.print(i+" ");
        }//6.For-Each循环打印出反转后的数组
    }
    public static int[] printRe(int[] arrays){
          
          
        //1.返回值为整型数组,所以printRe为数组类型方法,用int[]
        int[] result = new int[arrays.length];
        //2.创建一个,与arrays数组长度相等的数组result用于储存反转后的数组元素
        for (int i = 0; i < arrays.length; i++){
          
          
             result[arrays.length-i-1] = arrays[i];
        }//3.反转数组元素
        return result;//4.返回反转后的数组
    }
    

    若题目条件没有限制,上述代码可简化为:

    public static void main(String[] args) {
          
          
        int[] arrays = {
          
          1,2,3,4,5};
        reserve(arrays);//调用方法reserve()
    }
    public static void reserve(int[] arrays){
          
          
        //此方法没有返回值,因使用void类型
        for (int i = arrays.length - 1; i >= 0; i--) {
          
          
            System.out.print(arrays[i]+" ");
        }//反转数组并输出
    }
    

2、二维数组

二维数组是特殊的一维数组,其每一个元素都是一个一维数组。

  • 二维数组的动态初始化:

    type[][] typeName = new type[length1][length2]
    //二维数组类型为type,名称为typeName,有length1行,length2列
        【例】
    int[][] nums = new int[3][5]
    //声明并创建了int类型的二维数组nums,该数组有3行5列
    //该二维数组元素从nums[0][0]到nums[2][4]共3*5=15个数
    
  • 获取数组长度:

    nums.length获取的长度是 行数,nums[i].lenght获取的长度是第i行的元素个数

    上述例子中,nums.length = 5;nums[i].lenght = 3。

  • 二维数组的输出:

    for (int i = 0; i < arrays.length; i++) {
          
          
        for (int j = 0; j < arrays[i].length; j++) {
          
          
            System.out.print(arrays[i][j]+" ");
        }
        System.out.println();//输入完一行就换行
    }
    

3、Arrays类

数组的工具类java.util.Arrays,使用之前需要导包即import java.util.Arrays;

输出数组元素:通过 toString 方法,打印数组。

对数组排序:通过 sort 方法,按升序。

【例4】

import java.util.Arrays;
public class Test {
    
    
    public static void main(String[] args) {
    
    
        int[] a = {
    
    1,9,8,3,5,2,7};
        System.out.println(Arrays.toString(a));//打印数组
        Arrays.sort(a);//对数组排序
        System.out.println(Arrays.toString(a));
    }
}//[1, 9, 8, 3, 5, 2, 7]
//[1, 2, 3, 5, 7, 8, 9]

4、冒泡排序

对于一组数,依次比较相邻两数的大小(1和2,2和3,3和4…),并将较大(小)的数交换到后面,重复执行该组数的(个数-1)次后,就能得到一组顺序(逆序)排列的数列。

这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),故名“冒泡排序”。

【例5】代码实现:排序一组数

public static void sort(int[] arrays){
    
    
    for (int i = 0; i < arrays.length-1; i++) {
    
    
        for (int j = 0; j < arrays.length-1; j++) {
    
    
            if( arrays[j] > arrays[j+1]){
    
    
                int x = arrays[j];
                arrays[j] = arrays[j+1];
                arrays[j+1] = x;//5~7行,交换j和j+1的数字的位置
            }
        }
    }
}//内循环用于比较和调位置,外循环用于重复

【思考】以上代码,对于任何数组,都要执行( length-1 )^2次,对于本身就是顺序排列(或者调位次数很少就能完成排序)的数组,这样显然很浪费时间。

因此可以引入判断标志flag,在外循环里声明int flag=0,并在内循环的 if 中改变flag的值(flag=1),这样可以判断:

1、如果flag值改变,说明经历了if中的调位(调换位置)过程,说明正在排序,

2、反之,如果flag的值没有改变,说明经历了完整的内循环(从头到尾的相邻比较),并没有出现调位过程,即,数组已经排序完毕,可以提前推出排序过程,从而减少不必要的比较过程。

这段确实很难理解,我已经尽力描述的通俗易懂了。。。

代码修改后:

public static void sort(int[] arrays){
    
    
    for (int i = 0; i < arrays.length-1; i++) {
    
    
        int flag = 0;
        for (int j = 0; j < arrays.length-1; j++) {
    
    
            if( arrays[j] > arrays[j+1]){
    
    
                int x = arrays[j];
                arrays[j] = arrays[j+1];
                arrays[j+1] = x;
                flag = 1;
            }
        }
        if(flag == 0){
    
    //在内循环完成后判断是否改变了flag的值
            break;//如果flag没有改变,即数组已经排序完毕,退出外循环
        }
    }
}

稀疏数组(扩展)

稀疏数组

猜你喜欢

转载自blog.csdn.net/weixin_46330563/article/details/114994705