• java数据结构1--数组、排序和Arrays工具类


    数组:Array

    • 数组的定义
    • 数组的内存结构
    • 数组定义常见问题
    • 数组常见操作
    • Java参数传递问题--值传递
    • 二维数组

    1.数组概念

    同一种类型数据的集合,可以是基本数据类型,也可以是引用数据类型。

    数组的特点:

    1. 数组存储的都是相同数据类型的元素(相同数据类型
    2. 数组的长度也就是数组中元素的个数(固定长度
    3. 元素从0开始编号,编号也称“索引”:index(下标,角标)(从零开始
    4. 数组中元素的访问方式是通过数组名+索引的方式:arr[1](索引访问

    数组的定义格式

    2.数组的初始化

    初始化方式1:
    动态初始化:数组的创建和元素的赋值分开进行
    格式:
    元素类型[] 数组名 = new 元素类型[数组长度];
    int[] arr = new int[3];

     


    初始化方式2:
    静态初始化:数组创建时就给数组元素赋值
    格式:
    元素类型[] 数组名 = new 元素类型[]{元素1,元素2,…};
    int[] arr = new int[]{2,0,3,1};
    静态初始化的简化写法
    int[] arr = {2,0,3,1};

    直接打印数组类型的变量,会发现结果是一段看不懂的字符串,这就是引用数据类型变量的特点,它实际上代表的是一段内存空间的十六进制表示形式.真正的数据在JVM的堆内存空间中。

    note:动态初始的构成元素都是默认是初始化成默认值的。

    3.内存结构

    Java程序在运行时,为了提高运行效率,对内存进行了不同区域的划分,每一种区域都有特定的处理数据的方式和内存管理方式
    主要有以下几种:

    • 栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放
    • 堆内存:存放数组和对象,通过new建立的实例都存放在堆内存中

    每一个实例都有内存地址值
    实例中的变量都有默认初始化值
    当实例不再被使用,会在不确定的时间被垃圾回收器回收

    • 方法区:存放类文件和方法(面向对象部分再讲解)
    • 本地方法栈:供本地方法使用,与操作系统相关
    • 程序计数器--Program Counter:对字节码文件计数

    数组的内存结构:不属于四类八种,所以占用两种内存

    4.数组操作常见问题

    5.数组的遍历

    数组遍历:依次访问每个元素,访问的次数就是元素的个数,访问次数的确定:length属性(数组名.length)。

    获取一个数组的最值(最大值,最小值)
    改写:用键盘录入数组的长度和元素值
    改写:数组元素随机生成,并获取最值
    普通查找:获取指定元素第一次出现的索引
    数组的复制:重点考察是否需要返回值
    合并两个数组
    data1 = [1,2,3]  data2 = [4,5,6]
    练习:随机生成两个数组,并合并
    抽取奇数索引的元素(偶数的自己练习)
    数组的逆序(注意返回值类型)
    练习
    public class ArrayDemo4{
        public static void main(String[] args){
            int[] arr = {8,5,6,9,-10,4};
            System.out.println("最大值是: " + getMax(arr));
            System.out.println("最小值是: " + getMin(arr));
        }
        
        //自定义方法,获取一个数组的最大值
        public static int getMax(int[] arr){
            int max = arr[0];
            //遍历余下的数,比较,大的就放在max中
            for(int i = 1;i<arr.length;i++){
                if(arr[i] > max){
                    max = arr[i];
                }
            }
            //
            return max;
        }
        
        //
        public static int getMin(int[] arr){
            int min = arr[0];
            for(int i = 1;i<arr.length;i++){
                if(arr[i] < min){
                    min = arr[i];
                }
            }
            return min;
        }
        
    }
    获取一个int数组的最值
    public class ArrayDemo5{
        public static void main(String[] args){
            int[] arr = new int[5];
            //循环中产生随机值,并且赋值给元素
            for(int i = 0;i<arr.length;i++){
                int r = (int)(Math.random() * 100 ) + 1;
                arr[i] = r;
            }
            
            //打印数组元素
            printArray(arr);
            
            //获取最值
            System.out.println("最大值是: " + getMax(arr));
            System.out.println("最小值是: " + getMin(arr));
            
        }
        
        //
        public static int getMax(int[] arr){
            int max = arr[0];
            for(int i = 1;i<arr.length;i++){
                if(arr[i] > max){
                    max = arr[i];
                }
            }
            return max;
        }
        
        public static int getMin(int[] arr){
            int min = arr[0];
            for(int i = 1;i<arr.length;i++){
                if(arr[i] < min){
                    min = arr[i];
                }
            }
            return min;
        }
        
        //
        public static void printArray(int[] arr){
            for(int i = 0;i<arr.length;i++){
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
    }
    在16-78之间产生5个随机数组成数组,并求出其中的最值
    public class ArrayDemo6{
        public static void main(String[] args){
            Scanner s = new Scanner(System.in);
            System.out.print("输入元素的个数:");
            int n = s.nextInt();
            
            //
            int[] arr = new int[n];
    
            //赋值
            for(int i = 0;i<arr.length;i++){
                System.out.println("输入第" + (i+1) + "个数:");
                arr[i] = s.nextInt();
            }
            
            //
            printArray(arr);
        }
        
        //
        public static void printArray(int[] arr){
            for(int i = 0;i<arr.length;i++){
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    }
    改写:用键盘录入数组的长度和元素值
    public class ArrayDemo7{
        public static void main(String[] args){
            int[] arr = {1,2,3,4,5,10,8,2};
            Scanner s = new Scanner(System.in);
            System.out.println("输入要找的元素:");
            int value = s.nextInt();
            int index = getIndex(arr,value);
            
            //根据返回值判断是否找到指定元素
            if(index == -1){
                System.out.println("没有找到对应的元素");
            }else{
                System.out.println("第一次出现的索引是: " + index);
            }
        }
        
        //int
        //int[] arr,int value
        public static int getIndex(int[] arr,int value){
            /*
            for(int i = 0;i<arr.length;i++){
                if(arr[i] == value){
                    return i;
                }
            }
            //程序执行到这,意味着没有发现和参数相等的元素,那就返回一个不存在的索引值
            return -1;
            */
            
            //定义变量,保存返回值
            int index = -1;
            for(int i = 0;i<arr.length;i++){
                if(arr[i] == value){
                    index = i;
                    break;//不加break,如果多次出现这个值,那么这里得到的是最后一次出现的索引
                }
            }
            return index;
        }
    }
    普通查找:获取指定元素第一次出现的索引
    public class ArrayDemo8{
        public static void main(String[] args){
            
            int[] arr = {3,5,2,0};
            int[] res = copyArray(arr);
            
            printArray(res);
            
            System.out.println(arr == res);//true false
            
        }
        
        //
        public static void printArray(int[] arr){
            for(int i = 0;i<arr.length;i++){
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        //自定义方法:实现数组的复制
        public static int[] copyArray(int[] src){
            //创建一个新的数组:和源数组一样长
            int[] dest = new int[src.length];
            //循环赋值
            for(int i = 0;i<src.length;i++){
                dest[i] = src[i];
            }
            return dest;
        }
        
        
    }
    数组的复制:重点考察是否需要返回值
    /*
    合并两个数组
    data1 = [1,2,3]  data2 = [4,5,6]
    
    分析:先创建一个大的数组:特点长度等于两个小数组长度之和.
    然后依次赋值,重点是目标数组的索引的控制.
    
    练习:随机生成两个数组,并合并
    
    随机生成两个长度在1-10以内的数组,元组值范围:1-100
    然后合并两个数组.
    
    */
    
    public class ArrayDemo9{
        public static void main(String[] args){
            int[] data1 = {1,2,3};
            int[] data2 = {4,5,6,7,8,9};
            
            int[] dest = merge(data1,data2);
            
            printArray(dest);
        }
        
        //自定义方法,实现数组的合并
        public static int[] merge(int[] arr1,int[] arr2){
            //创建一个大数组
            int[] dest = new int[arr1.length + arr2.length];
            int index = 0;
            for(int i = 0;i<arr1.length;i++){
                dest[index++] = arr1[i];
                // index++;
            }
            
            for(int i = 0;i<arr2.length;i++){
                dest[index++] = arr2[i];
                // index++;
            }
            
            /*
            //循环赋值
            for(int i = 0;i<arr1.length;i++){
                dest[i] = arr1[i];
            }
            
            for(int i = 0;i<arr2.length;i++){
                dest[arr1.length + i] = arr2[i];
            }
            */
            
            return dest;
            
        }
        
        //
        public static void printArray(int[] arr){
            for(int i = 0;i<arr.length;i++){
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        
    }
    合并两个数组
    /*
    
    随机生成两个长度在1-10以内的数组,元素值范围:1-100
    然后合并两个数组.
    
    */
    public class ArrayDemo10{
        public static void main(String[] args){
            int l1 = (int)(Math.random() * 10) + 1; 
            int[] arr1 = new int[l1];
            int l2 = (int)(Math.random() * 10) + 1; 
            int[] arr2 = new int[l2];
            
            //循环赋值
            for(int i = 0;i<arr1.length;i++){
                arr1[i] = (int)(Math.random() * 100) + 1;
            }
            //循环赋值
            for(int i = 0;i<arr2.length;i++){
                arr2[i] = (int)(Math.random() * 100) + 1;
            }
            
            //打印
            System.out.println("第一个数组是: ");
            printArray(arr1);
            System.out.println("-------------");
            System.out.println("第二个数组是: ");
            printArray(arr2);
            System.out.println("-------------");
            System.out.println("合并之后的数组是: ");
            printArray(merge(arr1,arr2));
            
        }
        
        //打印数组
        public static void printArray(int[] arr){
            System.out.print("[");
            for(int i = 0;i<arr.length;i++){
                if(i == arr.length - 1){
                    System.out.print(arr[i] + "]");
                }else{
                    System.out.print(arr[i] + ", ");
                }
            }
            System.out.println();
        }
        
        //合并数组
        public static int[] merge(int[] src1,int[] src2){
            int[] dest = new int[src1.length + src2.length];
            int index = 0;
            for(int i = 0;i<src1.length;i++){
                dest[index++] = src1[i];
            }
            
            for(int i = 0;i<src2.length;i++){
                dest[index++] = src2[i];
            }
            return dest;
        }
        
    }
    合并两个数组
    public class ArrayDemo11{
        public static void main(String[] args){
            int[] arr = {1,2,3,4,5,6,7,8,9,10};
            
            int[] odd = getOdd(arr);
            printArray(odd);
            
            int[] even = getEven(arr);
            printArray(even);
            
            
        }
        
        //自定义方法,抽取偶数索引的元素
        public static int[] getEven(int[] arr){
            //计算偶数元素的个数
            int n = (arr.length + 1) / 2;
            //创建新数组
            int[] dest = new int[n];
            int index = 0;
            //循环赋值
            for(int i = 0;i<arr.length;i += 2){
                dest[index++] = arr[i];
            }
            return dest;
        }
        
        //自定义方法,抽取奇数索引的元素
        public static int[] getOdd(int[] arr){
            //计算奇数索引的个数
            int n = arr.length / 2;
            //创建目标数组
            int[] dest = new int[n];
            int index = 0;
            //赋值
            for(int i = 0;i<arr.length;i++){
                if(i % 2 == 1){
                    dest[index++] = arr[i];
                }
            }
            return dest;
        }
        
        //打印数组
        public static void printArray(int[] arr){
            System.out.print("[");
            for(int i = 0;i<arr.length;i++){
                if(i == arr.length - 1){
                    System.out.print(arr[i] + "]");
                }else{
                    System.out.print(arr[i] + ", ");
                }
            }
            System.out.println();
        }
    }
    抽取奇数索引的元素
    public class ArrayDemo12{
        public static void main(String[] args){
            int[] arr = {1,2};
            
            reverse(arr);
            printArray(arr);
            
        }
        
        //打印数组
        public static void printArray(int[] arr){
            System.out.print("[");
            for(int i = 0;i<arr.length;i++){
                if(i == arr.length - 1){
                    System.out.print(arr[i] + "]");
                }else{
                    System.out.print(arr[i] + ", ");
                }
            }
            System.out.println();
        }
        
        //
        public static void reverse(int[] arr){
            int n = arr.length / 2;
            for(int i = 0;i<n;i++){
                int temp = arr[i];
                arr[i] = arr[arr.length - 1 - i];
                arr[arr.length -1 - i] = temp;
            }
        }
    }
    数组的逆序(注意返回值类型)void

    6.Java中参数传递(实参->形参)的问题

    public class Test5 {
    
        public static void main(String[] args) {
    
            int[] a = { 1, 2, 3, 4, 5 };
            int[] b = new int[a.length];
    
            System.out.println("交换前:");
            print(a);
            print(b);
    
            b = swap(a);//交换
            
            System.out.println("交换后:");
            print(a);
            print(b);
        }
    
        public static void print(int[] arr){
            System.out.print("[");
            for(int i = 0;i<arr.length;i++){
                if(i == arr.length - 1){
                    System.out.print(arr[i] + "]");
                }else{
                    System.out.print(arr[i] + ", ");
                }
            }
            System.out.println();
        }
        
    
        private static int[] swap(int[] c) {
            int[] tmp = new int[c.length];
            for (int j = 0; j < c.length; j++) {
                tmp[j] = c[c.length - j - 1] + 10;
            }
            return tmp;
        }
    }
    值传递1

    交换前:
    [1, 2, 3, 4, 5]
    [0, 0, 0, 0, 0]
    交换后:
    [1, 2, 3, 4, 5]
    [15, 14, 13, 12, 11]

    swap()方法时,数组a将其地址传递c,所以a和c是指向同一个数组。
    但在swap方法中,新生成了一个数组tmp,改变的是tmp数组,返回时把tmp数组的首地址送数组b.所以b指向改tmp.

    public class Test6 {
        public static void main(String[] args) {
            int[] a = { 1, 2, 3, 4, 5 };
            int[] b = new int[a.length];
            System.out.println("交换前:");
            print(a);
            print(b);
            b = swap(a);
            System.out.println("交换后:");
            print(a);
            print(b);
        }
    
        public static void print(int[] arr){
            System.out.print("[");
            for(int i = 0;i<arr.length;i++){
                if(i == arr.length - 1){
                    System.out.print(arr[i] + "]");
                }else{
                    System.out.print(arr[i] + ", ");
                }
            }
            System.out.println();
        }
        
    
        private static int[] swap(int[] c) {
            for (int j = 0; j < c.length; j++) {
                c[j] = c[c.length - j - 1] + 10;
            }
            return c;
        }
    }
    值传递2
    交换前:
    [1, 2, 3, 4, 5]
    [0, 0, 0, 0, 0]
    交换后:
    [15, 14, 13, 24, 25]
    [15, 14, 13, 24, 25]

    说明: 在该程序中,在调用swap()方法时,数组a将其地址传递给数组c,所以a和c是指向同一个数组。
    返回时,数组b不再指向原来的数组,而指向c所在的数组。
    注: JAVA中参数传递时是值传递,引用型与基本数据类型是不同的.

     7 二维数组

    7.1二维数组的概念 

    7.2 二维数组的定义

    注意事项:

    1.使用格式1,2时必须指定第一维长度
    2.动态,静态初始化不能同时使用

    7.3二维数组的遍历

    8 数组的排序(排序算法)

    8.1冒泡排序:bubble

    冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复以上过程,仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到最大数前的一对相邻数,将小数放前,大数放后,第二趟结束,在倒数第二个数中得到一个新的最大数。如此下去,直至最终完成排序。

    /*
     * 冒泡排序:
     *     相邻的元素两两比较.大的往后放.
     */
    public class BubbleSortDemo {
    
        public static void main(String[] args) {
            int[] arr = {9,5,2,0,4,5,5,7};
            bubbleSort(arr);
            printArray(arr);
    
        }
        
        public static void printArray(int[] arr){
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        //
        public static void bubbleSort(int[] arr){
            
            //外层循环控制的是比较的趟数:固定是元素个数-1
            for(int i = 0;i<arr.length - 1;i++){
                //内层循环控制的是两两比较元素的索引
                for(int j = 0;j<arr.length - 1 - i;j++){
                    if(arr[j] > arr[j + 1]){
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            
        }
    
    }
    冒泡排序

    8.2 比较排序:compare(选择排序:select)

    /*
     * 选择排序
     */
    public class SelectSortDemo {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] arr = {9,5,2,7,0,6,4,7};
            selectSort(arr);
            print(arr);
        }
        
        public static void print(int[] arr){
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        public static void selectSort(int[] arr){
            //外层控制的是比较的趟数
            for (int i = 0; i < arr.length -1; i++) {
                //内层循环控制的是两两比较元素的索引值
                for (int j = i + 1; j < arr.length; j++) {
                    //
                    if(arr[i] > arr[j]){
                        int temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
            
        }
    
    }
    选择排序
    public class SelectSortDemo2 {
    
        public static void main(String[] args) {
            //产生1000个元素的数据进行比较
            int[] arr1 = getArray();
            int[] arr2 = arrayCopy(arr1);
            print(arr1);
            print(arr2);
            long start = System.currentTimeMillis();
            selectSort(arr1);
            System.out.println(System.currentTimeMillis() - start);
            
            start = System.currentTimeMillis();
            selectSort2(arr2);
            System.out.println(System.currentTimeMillis() - start);
            
            System.out.println("排序后");
            print(arr1);
            print(arr2);
            
        }
        
        public static int[] arrayCopy(int[] arr){
            int[] dest = new int[arr.length];
            System.arraycopy(arr, 0, dest, 0, arr.length);
            return dest;
        }
        
        //随机生成1000个元素的int数组
        public static int[] getArray(){
            int[] arr = new int[1000];
            for(int i = 0;i<arr.length;i++){
                arr[i] = (int)(Math.random() * 1000);
            }
            return arr;
        }
        
        public static void print(int[] arr){
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
        
        public static void selectSort(int[] arr){
            int count = 0;
            //外层控制的是比较的趟数
            for (int i = 0; i < arr.length -1; i++) {
                //内层循环控制的是两两比较元素的索引值
                for (int j = i + 1; j < arr.length; j++) {
                    //
                    if(arr[i] > arr[j]){
                        int temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                        count++;
                    }
                }
            }
            
            System.out.println("优化前的方法中,交换的次数是: " + count);
        }
    
        public static void selectSort2(int[] arr){
            int count = 0;
            //外层控制的是比较的趟数
            for (int i = 0; i < arr.length -1; i++) {
                //记录要确定的元素的索引号
                int index = i;
                
                //内层循环控制的是两两比较元素的索引值
                for (int j = i + 1; j < arr.length; j++) {
                    //
                    if(arr[index] > arr[j]){
                        index = j;
                    }
                }
                
                //对index值进行判断
                if(i != index){
                    int temp = arr[i];
                    arr[i] = arr[index];
                    arr[index] = temp;
                    count++;
                }
            }
            System.out.println("优化后的方法中,交换的次数是: " + count);
        }
    }
    选择排序比较

    9 Arrays工具类

    一下皆为静态方法。

    1. binarySearch:复制指定的数组
    2. copyOf:复制指定的数组
    3. copyOfRange:将指定数组的指定范围复制到一个新数组
    4. deepEquals:如果两个指定数组彼此是深层相等
    5. deepToString:返回指定数组“深层内容”的字符串表示形式。
    6. deepHashCode:基于指定数组的“深层内容”返回哈希码。
    7. equals:如果两个指定的 某 型数组彼此相等,则返回 true。
    8. fill: 将指定的 某型 值分配给指定 某 型数组的每个元素。
    9. sort:根据元素的自然顺序对指定某类型数组按升序进行排序。
    10. toString:返回指定数组内容的字符串表示形式。

    单独介绍一下二分查找:

    public class BinarySearchDemo {
    
        public static void main(String[] args) {
    
            int[] arr = {1,2,3,7,9,20};
            int index = getIndex(arr,1);
            if(index == -1){
                System.out.println("not found");
            }else{
                System.out.println("the index is : " + index);
            }
        }
        
        //二分查找算法
        public static int getIndex(int[] arr,int value){
            
            int min = 0;
            int max = arr.length - 1;
            
            int mid = (min + max)/2;
            
            while(true){
                //
                if(arr[mid] == value){
                    return mid;
                }else if(arr[mid] > value){
                    max = mid - 1;
                }else{
                    min = mid + 1;
                }
                //重新计算mid的值
                mid = (min + max)/2;
                //
                if(min > max){
                    return -1;
                }
            }
        }
    }
    二分查找:前提:数组必须有序:
  • 相关阅读:
    关于在Eclipse中使用正则表达式替换的一点记录(使用正则表达式的分组)
    C#学习笔记(六):可空类型、匿名方法和迭代器
    C#学习笔记(五):泛型
    C#学习笔记(四):委托和事件
    C#学习笔记(三):值类型、引用类型及参数传递
    C#学习笔记(二):继承、接口和抽象类
    Unity3D之AssetBundle学习:Android上运行笔记
    js arguments 内置对象
    JS面向对象高级特性
    js 阻止事件冒泡 支持所有主流浏览器
  • 原文地址:https://www.cnblogs.com/wqbin/p/11176258.html
Copyright © 2020-2023  润新知