美文网首页数据结构程序员Java学习笔记
Java语言基础9--引用数据类型之数组

Java语言基础9--引用数据类型之数组

作者: buzhidao_ | 来源:发表于2016-11-24 14:37 被阅读129次

    什么是数组

    数组是一种数据结构,用来存储同一类型的集合.
    数组中的每一个数据称之为数组元素,数组中的元素以索引来表示其存放的位置,索引从0开始.

    数组的定义

    第一种方式:类型[] 数组名; 如 int[] nums; **
    第二种方式:
    类型 数组名[]; 如 int nums[];**
    大多数Java程序员喜欢使用第一种风格,因为它把数据类型int[],和变量名num分开了.

    数组的初始化

    Java中数组必先初始化后才能使用.
    初始化就是给数组元素分配内存,并为每个元素赋初始值。

    初始化数组的两种方式:
    - 静态初始化:
    语法格式:类型[] 数组名 = new 数组类型[]{元素1,元素2,元素3,...元素n};
    简化语法:类型[] 数组名 = {元素1,元素2,元素3...元素n};
    - 动态初始化:
    如果我们事先不知道数组里存储哪些数据,只知道需要存储数据的个数,此时可以使用动态初始化方式。
    动态初始化:初始化时由我们指定数组的长度,系统自动为数组元素分配初始值。
    格式:类型[] 数组名 = new 数组类型[数组长度];

    不同数据类型的初始值.png
    //数组初始化
    public class InitDemo {
        public static void main(String[] args) {
            //静态初始化
            int[] num = new int[] { 1, 2, 3, 4, 5 };
            int[] num1 = { 1, 2, 3, 4, 5 };//简单写法
            //只知道要存放数据的个数,不知道具体内容--动态初始化
            int[] num2 = new int[5];//不同数据的动态初始化会有不同的初始值
        }
    }
    

    注意:无论,以哪种方式初始化数组,一旦初始化完成,数组的长度就固定了,不能改变,除非重新初始化。也就是说数组是定长的。如果需要经常扩展数组的大小,应该使用另一种数据结构--数组列表(ArrayList).

    数组初始化内存分析

    数组初始化内存分析.png 一维数组内存分析

    简单数组排序算法

    - 冒泡排序(Bubble Sort):
    思路:对未排序的各元素从头到尾依次比较相邻的两个元素大小关系,若大于则交换位置,经过第一轮比较排序后可得出最大值,然后使用同样的方法把剩下的元素逐个比较即可。
    如果一共有N个元素,那么一共要进行N-1轮比较,第M轮要进行N-M次比较。

    import java.util.Arrays;
    //冒泡排序 -- 升序为例
    public class BubbleSortDemo {
        public static void main(String[] args) {
            int[] num = { 13, 6, 2, 1, 4, 7, 8, 9 };
            bubbleSort(num);
            System.out.println(Arrays.toString(num));
            Arrays.binarySearch(num, 5);
        }
    
        private static void bubbleSort(int[] a) {
            //1.确定比较次数,N个元素,就要比较N - 1次
            for (int time = 1; time <= a.length - 1; time++) {
                //2.每次都是从最低位(索引为0处)开始,进行相邻的数值比较,第一轮出最大值
                //类似于水里冒泡泡,每次都是水底开始,大的气泡先浮上来
                for (int index = 0; index < a.length - time; index++) {
                    if (a[index] > a[index + 1]) {
                        int temp = a[index];
                        a[index] = a[index + 1];
                        a[index + 1] = temp;
                    }
                }
            }
    
        }
    }
    

    - 选择排序(Selection Sort):
    基本思路:选择某个索引位置的元素,然后和后面元素依次比较,若大于则交换位置,经过第一轮比较排序后可得出最小值,然后使用同样的方法把剩下的元素逐个比较即可。
    第一轮会选出最小值,第二轮会选出第二小的值,直到最后。
    选择排序每一轮只进行一次交换,相对于冒泡排序效率高一些。

    import java.util.Arrays;
    
    //选择排序--以升序为例
    public class SelectionSortDemo {
        public static void main(String[] args) {
            int[] num = { 12, 13, 2, 1, 4, 7, 8, 9 };
            selectionSort(num);
            System.out.println(Arrays.toString(num));
        }
    
        public static void selectionSort(int[] num) {
            //1.N个数要进行N-1轮
            for (int time = 1; time < num.length; time++) {
                //选择排序,类似于排队,找出最矮的,放在第一位,第二矮的放在第二位....
                for (int index = time; index < num.length; index++) {
                    if (num[time - 1] > num[index]) {
                        int temp = num[index];
                        num[index] = num[time - 1];
                        num[time - 1] = temp;
                    }
                }
            }
        }
    }
    

    -二分查找(折半查找)
    采用二分法查找时,数据需是排好序的
    二分查找的基本思想是将n个元素分成大致相等的两部分,取a[n/2]与x做比较,如果x=a[n/2],则找到x,算法中止;如果x<a[n/2],则只要在数组a的左半部分继续搜索x,如果x>a[n/2],则只要在数组a的右半部搜索x.
    当数据量很大适宜采用该方法。

    例如:猜数游戏:
    猜一个从1到100之间的数,为了能用最少的次数猜中,必须从50开始猜。如果你猜的偏小了,那么就能推出那个数在50到100之间,所以马上猜75。但如果你猜偏大了,你也能明白哪个说在1到50之间,所以马上猜25。如此重复,范围越来越小,直到猜到为止。

    //二分法查找--前提:数组是有序的,一般都是升序
    public class BinarySearchDemo {
        public static void main(String[] args) {
            int[] num = { 1, 3, 5, 7, 9 };
            int ret = binarySearch(num, 5);
            System.out.println(ret);
        }
    
        private static int binarySearch(int[] num, int key) {
            int low = 0;
            int high = num.length - 1;
            while (low <= high) {
                int mid = (low + high) >>> 1;//右移1位,就是除以2,但是效率更高
                int midVal = num[mid];
                if (midVal < key)
                    low = mid + 1;
                else if (midVal > key)
                    high = mid - 1;
                else
                    return mid;
            }
            return -1;
        }
    }
    

    多维数组

    如果每个变量都是一维数组,那这个装多个一维数组的数组是什么呢?也就是说现在数组里还有数组,此时我们习惯称为二维数组,同理什么是三维数组呢?
    一维数组:数组中的每一个元素都是一个值.
    二维数组:数组在的每一个元素都是一维数组.
    三维数组:数组中的每一个元素都是二维数组.
    注意:在Java中没有真正的多维数组的概念,我们习惯称之为数组中的数组.
    注意区分和C/C++中的多维数组
    详细可以看这篇文章:http://blog.csdn.net/u012110719/article/details/46288893

    二维数组内存分析

    二维数组内存分析.png

    方法的可变参数

    遇到什么问题

    求两个数之和,需要一个方法,该方法有两个参数,求5个数之和,需要重载一个方法,该方法有5个参数,求100个数之和、1000个数之和、10000个数之和,方法的参数列表会很长很长

    我们使用数组解决了同类型的多参数问题.但是,调用者需要先把数据封装到一个数组中,再传递给求和方法.,很不爽!
    怎么解决
    解决方案:使用方法的可变参数机制.
    方法的可变参数其实底层就是数组.
    ** 注意:**
    1:可变参数只能运用于方法的参数中.
    2:其本质就是数组,是Java5的一个语法糖.
    3:可变参数必须作为方法的最后一个参数.

    //方法的可变参数
    public class AlterArgsDemo {
        public static void main(String[] args) {
            int ret = getSum(1, 2, 3);
            System.out.println(ret);//6
            ret = getSum(1, 2);
            System.out.println(ret);//3
            ret = getSum(1, 2, 3, 4, 5);
            System.out.println(ret);//15
        }
    
        public static int getSum(int... arr) {
            int sum = 0;
            for (int i : arr) {
                sum += i;
            }
            return sum;
        }
    }
    

    相关文章

      网友评论

        本文标题:Java语言基础9--引用数据类型之数组

        本文链接:https://www.haomeiwen.com/subject/sqpbpttx.html