一、Java语言基础(5)_数组高级——多维数组

2018-04-27

 与其临渊羡鱼,不如退而结网

数组高级——多维数组

一、定义

 

二、初始化和内存分析

  以二维数组为例

  • 静态初始化:  

    int[][] arr = new int[][]{

      {1,2,3},

      {4,5},

      {6}

    };

 

 

  • 动态初始化:

    int[][] arr = new int[3][5];  //创建一个长度为3的二维数组,每一个元素(一维数组)的长度为5

三、java5对数组的新语法支持

  • 增强for循环:foreach

    foreach的语句格式: 

    for(数组元素类型t 数组元素变量x : 遍历对象obj){ 
         引用了x的java语句; 
    } 

    需求:定义一个数组使用循环迭代出数组的每一个元素

    代码:

 1 //增强for循环:foreach
 2 
 3 class ForEachDemo 
 4 {
 5     public static void main(String[] args) 
 6     {
 7         //使用for循环迭代元素
 8         int[] arr = new int[]{10,20,30,40,50};
 9         for(int index = 0 ; index < arr.length; index++){
10             System.out.println(arr[index]);
11         }
12         System.out.println("------------------");
13         //使用foreach循环迭代元素
14         for(int ele : arr){
15             System.out.println(ele);
16         }
17     }
18 }

输出结果:

  • 方法的可变参数 (变的是参数的个数,不是参数类型)

    需求:定义一个方法来统计使用数组传递的总和

    普通方法:

 1 //方法的可变参数
 2 
 3 class VarArgsDemo 
 4 {
 5     public static void main(String[] args) 
 6     {
 7         double[] ps = new double[]{1.0,2.0,3.0,4.0,5.0};
 8         double sum = getSum(ps);
 9         System.out.println(sum);
10     }
11     //计算商品的总和(普通方法)
12     static double getSum(double[] arr){
13         double sum = 0.0;
14         for(double price : arr){
15             sum = sum + price;
16         }
17         return sum;
18     }
19 }

    

输出结果:15.0

    可变参数方法:

 1 //方法的可变参数
 2 
 3 class VarArgsDemo 
 4 {
 5     public static void main(String[] args) 
 6     {
 7        double[] ps = new double[]{1.0,2.0,3.0,4.0,5.0};
 8         double sum = getSum(ps); 
9      System.out.println(sum);
10    }
11   //计算商品的总和(可变参数方法)
12   static double getSum(double ... arr){
13     double sum = 0.0;
14     for(double price : arr){
15       sum = sum + price;
16     }
17     return sum;
18 }
19 }

输出结果:15.0 

 

可变参数必须作为方法的最后一个参数,避免参数的歧义

推论:方法最多只有一个可变参数

四、数组算法

  1. 数组元素拷贝

    参考博客         java System.arrayCopy使用说明

    学会使用API

 

   2.排序算法

    排序:安照指定顺序排列出来

    升序:从小到大

    降序:从大到小

    排序的分类:  选择排序(直接选择排序、堆排序),  交换排序(冒泡排序、快速排序),  插入排序(直接插入排序、二分法插入排序、shell排序),  归并排序等。

 

    • 冒泡排序    

      a)原理:比较两个相邻的元素,将值大的元素交换至右端。

      b)思路:依次比较相邻的两个数,若大于则交换位置。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。

 

      c)举例说明:要排序数组:int[] arr={6,3,8,2,9,1};   

      第一趟排序:

        第一次排序:6和3比较,6大于3,交换位置:  3  6  8  2  9  1

        第二次排序:6和8比较,6小于8,不交换位置:3  6  8  2  9  1

        第三次排序:8和2比较,8大于2,交换位置:  3  6  2  8  9  1

        第四次排序:8和9比较,8小于9,不交换位置:3  6  2  8  9  1

        第五次排序:9和1比较:9大于1,交换位置:  3  6  2  8  1  9

      第一趟总共进行了5次比较, 排序结果:      3  6  2  8  1  9 

      ---------------------------------------------------------------------

      第二趟排序:

        第一次排序:3和6比较,3小于6,不交换位置:3  6  2  8  1  9

        第二次排序:6和2比较,6大于2,交换位置:  3  2  6  8  1  9

        第三次排序:6和8比较,6大于8,不交换位置:3  2  6  8  1  9

        第四次排序:8和1比较,8大于1,交换位置:  3  2  6  1  8  9

      第二趟总共进行了4次比较, 排序结果:      3  2  6  1  8  9

      ---------------------------------------------------------------------

      第三趟排序:

        第一次排序:3和2比较,3大于2,交换位置:  2  3  6  1  8  9

        第二次排序:3和6比较,3小于6,不交换位置:2  3  6  1  8  9

        第三次排序:6和1比较,6大于1,交换位置:  2  3  1  6  8  9

        第二趟总共进行了3次比较, 排序结果:         2  3  1  6  8  9

      ---------------------------------------------------------------------

      第四趟排序:

        第一次排序:2和3比较,2小于3,不交换位置:2  3  1  6  8  9

        第二次排序:3和1比较,3大于1,交换位置:  2  1  3  6  8  9

        第二趟总共进行了2次比较, 排序结果:        2  1  3  6  8  9

        ---------------------------------------------------------------------

      第五趟排序:

        第一次排序:2和1比较,2大于1,交换位置:  1  2  3  6  8  9

        第二趟总共进行了1次比较, 排序结果:  1  2  3  6  8  9

      ---------------------------------------------------------------------

      最终结果:1  2  3  6  8  9

      ---------------------------------------------------------------------

      由此可见:N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数。

      

      代码实现:

/*
 * 冒泡排序
 */
public class BubbleSort {
  public static void main(String[] args) {
    int[] arr={6,3,8,2,9,1};
    System.out.println("排序前数组为:");
    for(int num:arr){//for-each循环
      System.out.print(num+" ");
    }
    for(int time = 0; i < arr.length-1; i++){//外层循环控制排序趟数
      for(int j = 0;j < arr.length-1-time; j++){//内层循环控制每一趟排序多少次
        if(arr[j]>arr[j+1]){
          int temp=arr[j];
          arr[j]=arr[j+1];
          arr[j+1]=temp;
        }
      }
    } 
    System.out.println();
    System.out.println("排序后的数组为:");
     for(int num:arr){
       System.out.print(num+" ");
     } 
  }
 }

  

    • 选择排序

       a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。(这里只介绍常用的简单选择排序)      

 

       b)直接选择排序算法的思想比较简单:(假设数据放在一个数组a中,且数组的长度是N)

        1:从a[0]-a[N-1]中选出最小的数据,然后与a[0]交换位置

        2:从a[1]-a[N-1]中选出最小的数据,然后与a[1]交换位置(第1步结束后a[0]就是N个数的最小值)

        3:从a[2]-a[N-1]中选出最小的数据,然后与a[2]交换位置(第2步结束后a[1]就是N-1个数的最小值)

        以此类推,N-1次排序后,待排数据就已经按照从小到大的顺序排列了。

        

        

      c)举例:

//选择排序
public class SelectionSort {
    public static void main(String[] args) {
        int[] arr={1,3,2,45,65,33,12};
        System.out.println("交换之前:");
        for(int num:arr){
            System.out.print(num+" ");
        }        
        //选择排序的优化
        for(int i = 0; i < arr.length - 1; i++) {// 做第i趟排序
            int k = i;
            for(int j = k + 1; j < arr.length; j++){// 选最小的记录
                if(arr[j] < arr[k]){ 
                    k = j; //记下目前找到的最小值所在的位置
                }
            }
            //在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
            if(i != k){  //交换a[i]和a[k]
                int temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }    
        }
        System.out.println();
        System.out.println("交换后:");
        for(int num:arr){
            System.out.print(num+" ");
        }
    }

}

   3.搜索算法

    从指定数组中去搜索某一个元素的索引是多少

 

    • 线性搜索(从头搜到尾或从尾搜到头)
    • 二分搜索(二分查找)

      a)二分查找又称折半查找,它是一种效率较高的查找方法。

      折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。 折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。

      b)折半查找法的优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

      c)二分算法步骤描述

        ① 首先确定整个查找区间的中间位置 mid = ( left + right )/ 2

        ② 用待查关键字值与中间位置的关键字值进行比较;

          若相等,则查找成功

          若大于,则在后(右)半个区域继续进行折半查找

          若小于,则在前(左)半个区域继续进行折半查找

        ③ 对确定的缩小区域再按折半公式,重复上述步骤。

        最后,得到结果:要么查找成功, 要么查找失败。折半查找

 

 

   4.Java自带数组工具类Arrays类

    查找API   java.util.Arrays

    

 

原文地址:https://www.cnblogs.com/sunNoI/p/8961452.html