四.数组、排序和查找

四.数组、排序和查找

数组是相同数据类型的多个数据的容器。 这些元素按线性顺序排列。所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;除最后一个 元素外,每一个元素都有唯一的后继元素。(“简单理解就是:一个跟一个顺序排列”)。

 

创建格式

格式 1. 数据类型[] 数组名称 = new 数据类型[数组长度];

格式 2. 数据类型[] 数组名称 = {数组内容 1,数组内容 2,数组内容 3...数组内容 n};

格式 3. 数据类型[] 数组名; 格式 3 属于只创建了数组引用名, 并未在内存创建数组空间。

格式 4. 数据类型[] 数组名称 = new 数据类型[]{内容 1,内容 2,内容 3...内容 n};

 

示例
public static void main(String[] args) {
   //演示 数据类型 数组名[]=new 数据类型[大小]
   //循环输入 5 个成绩,保存到 double 数组,并输出
   //步骤
   //1. 创建一个 double 数组,大小 5
   //(1) 第一种动态分配方式
   //double scores[] = new double[5];
   //(2) 第 2 种动态分配方式, 先声明数组,再 new 分配空间
   double scores[] ; //声明数组, 这时 scores 是 null
   scores = new double[5]; // 分配内存空间,可以存放数据
   //2. 循环输入
   // scores.length 表示数组的大小/长度
   //
   Scanner myScanner = new Scanner(System.in);
   for( int i = 0; i < scores.length; i++) {
       System.out.println("请输入第"+ (i+1) +"个元素的值");
       scores[i] = myScanner.nextDouble();
  }
   //输出,遍历数组
   System.out.println("==数组的元素/值的情况如下:===");
   for( int i = 0; i < scores.length; i++) {
       System.out.println("第"+ (i+1) +"个元素的值=" + scores[i]);
}
数组使用注意事项和细节

1) 数组是多个相同类型数据的组合,实现对这些数据的统一管理

2) 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。

3) 数组创建后,如果没有赋值,有默认值 int 0,short 0, byte 0, long 0, float 0.0,double 0.0,char \u0000,boolean false,String null

4) 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值 3 使用数组

5) 数组的下标是从 0 开始的。

6) 数组下标必须在指定范围内使用,否则报:下标越界异常,比如int [] arr=new int[5]; 则有效下

7) 数组属引用类型,数组型数据是对象(object)

8)数组的长度在创建时就固定了

 

数组添加/扩容
public static void main(String[] args) {
   /*
   要求:实现动态的给数组添加元素效果,实现对数组扩容。ArrayAdd.java
   1.原始数组使用静态分配 int[] arr = {1,2,3}
   2.增加的元素 4,直接放在数组的最后 arr = {1,2,3,4}
   3.用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
   思路分析
   1. 定义初始数组 int[] arr = {1,2,3}//下标 0-2
   2. 定义一个新的数组 int[] arrNew = new int[arr.length+1];
   3. 遍历 arr 数组,依次将 arr 的元素拷贝到 arrNew 数组
   4. 将 4 赋给 arrNew[arrNew.length - 1] = 4;把 4 赋给 arrNew 最后一个元素
   5. 让 arr 指向 arrNew ; arr = arrNew; 那么 原来 arr 数组就被销毁
   6. 创建一个 Scanner 可以接受用户输入
   7. 因为用户什么时候退出,不确定,老师使用 do-while + break 来控制
   */
   Scanner myScanner = new Scanner(System.in);
   //初始化数组
   int[] arr = {1,2,3};
   do {
       int[] arrNew = new int[arr.length+1]
       //遍历 arr 数组,依次将 arr 的元素拷贝到 arrNew 数组
       for(int i = 0; i < arr.length; i++) {
      arrNew[i] = arr[i];
      }
       System.out.println("请输入你要添加的元素");
       int addNum = myScanner.nextInt();
       //把 addNum 赋给 arrNew 最后一个元素
       arrNew[arrNew.length - 1] = addNum;
       //让 arr 指向 arrNew, arr = arrNew;
       //输出 arr 看看效果
       System.out.println("====arr 扩容后元素情况====");
       for(int i = 0; i < arr.length; i++) {
           System.out.print(arr[i] + "\t");
      }
       //问用户是否继续
       System.out.println("是否继续添加 y/n");
       char key = myScanner.next().charAt(0);
       if( key == 'n') { //如果输入 n ,就结束
      break;
  }
  }while(true);
   System.out.println("你退出了添加...");
}

 

冒泡排序法

下面我们举一个具体的案例来说明冒泡法。我们将五个无序:24,69,80,57,13 使用冒泡排序法将其排成一个从小到大的有 序数列。

public static void mian(String args[]){
public static void main(String[] args) {
      /**
        * 冒泡排序
        * 数组[24,69,80,57,13]
        */
      int temp = 0;
      int[] arr = {24, 69, 80, 57, 13};
      //每一轮比较将最大的数排到最后,一共要进行arr.length-1次排序,因此最外层循环为arr.length-1次
      for (int i = 0; i < arr.length - 1; i++) {
          //每一次循环需要进行arr.length-i-1次比较
          for (int 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;
              }
          }
      }
      for (int j = 0; j < arr.length; j++) {
          System.out.print(arr[j] + "\t");
      }
  }

}

 

二分查找 (折半查找)
        /**
        * 二分查找
        * 数组[21,33,49,50,61,77,89,90] 查找50
        */
      int[] arr = {21,33,49,50,61,77,89,90};
      int low = 0; // 开始位置
      int high = arr.length - 1; // 结束 位置
      int middle = 0;
      int target = 50;
      while(low <= high){
          middle = (low + high)/2;
          if(arr[middle] == target){
              System.out.println(middle);
              break;
          }else if(arr[middle] > target){
              high = middle-1;
          }else{
              low = middle+1;
          }
      }
      if(low > high) {
          System.out.println("未找到");
      }

 

多维数组

二维数组

动态初始化:

类型 数组名=new 类型[大小][大小]

public static void main(String[] args) {
  /*
  看一个需求:动态创建下面二维数组,并输出
  i = 0: 1
  i = 1: 2 2
  i = 2: 3 3 3 一个有三个一维数组, 每个一维数组的元素是不一样的
  */
  //创建 二维数组,一个有 3 个一维数组,但是每个一维数组还没有开数据空间
  int[][] arr = new int[3][];
  for(int i = 0; i < arr.length; i++) {//遍历 arr 每个一维数组
      //给每个一维数组开空间 new
      //如果没有给一维数组 new ,那么 arr[i]就是 null
      arr[i] = new int[i + 1];
      //遍历一维数组,并给一维数组的每个元素赋值
      for(int j = 0; j < arr[i].length; j++) {
      arr[i][j] = i + 1;//赋值
  }
  }
  System.out.println("=====arr 元素=====");
  //遍历 arr 输出
  for(int i = 0; i < arr.length; i++) {
  //输出 arr 的每个一维数组
      for(int j = 0; j < arr[i].length; j++) {
          System.out.print(arr[i][j] + " ");
      }
      System.out.println();//换行
  }
}

静态初始化:

定义 类型 数组名 = {{值 1,值 2..},{值 1,值 2..},{值 1,值 2..}}

比如: int arr = {{1,1,1}, {8,8,9}, {100}};

public static void main(String[] args) {
  /*
  int arr[][]={{4,6},{1,4,5,7},{-2}}; 遍历该二维数组,并得到和
  思路
  1. 遍历二维数组,并将各个值累计到 int sum
  */
  int arr[][]= {{4,6},{1,4,5,7},{-2}};
  int sum = 0;
  for(int i = 0; i < arr.length; i++) {
      //遍历每个一维数组
      for(int j = 0; j < arr[i].length; j++) {
          sum += arr[i][j];
  }
  }
  System.out.println("sum=" + sum);
}

二维数组使用细节和注意事项

1) 一维数组的声明方式有:

int[] x 或者 int x[]

2) 二维数组的声明方式有:

int y 或者 int[] y[] 或者 int y

3) 二维数组实际上是由多个一维数组组成的,它的各个一维数组的长度可以相同,也可以不相同。比如: map 是 一个二维数组

int map = {{1,2},{3,4,5}} 由 map[0] 是一个含有两个元素的一维数组 ,map[1] 是一个含有三个元素的一维数组构成,我们也称为列数不等 的二维数组

posted @ 2021-10-27 14:44  brysjs  阅读(216)  评论(0)    收藏  举报