java中的数组

数组相同类型数据的有序结合。数组描述的是相同类型的若干类型,按照一定的先后顺序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问他其元素。

 

 数组的特征:
         * 1.定义数组必须指定大小
         * 2.数组的每一个元素的内存都是连续的
         * 3.数组的随机访问操作,是一个常量时间 arr[index]
         * 4.每一个数组都内置了一个成员变量 length,表示数组的总长度
         * 5.数组增加元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的时间是线性时间
         * 6.数组删除元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的是时间线性时间
         * 7.数组的元素查找花费时间为线性时间,逐个遍历

 

 练习1•:定义数组一个长度为100的数组,每一个随机数在100-200之间,每5个换行输出该数组

 

 

 

输出数组方式:
输出100-200之间的随机数中的偶数
        // 输出数组方式一   标准for循环(常用)
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % 2 == 0) { 
                System.out.print(arr[i] + " ");
            }
        }
        System.out.println();
        // 输出数组方式二   foreach  arr.length
        for (int val : arr) {   //相当于把数组中的每一个数赋给变量val
            if (val % 2 == 0) {
                System.out.print(val + " ");
            }
        }
        System.out.println();
 

二维数组的内存分析:

 数组的常见方法:

       Arrays.copyOf     数组的扩容和缩容

   Arrays.toString     打印数组元素

   Arrays.deepToString   打印二维数组元素的值

        Arrays.fill         给数组初始化/重置

  Arrays.equals   比较两个数组的内容是否相等

 

//开辟一个有8个元素的数组,放200-300之间的数据
int arr[] = new int[8];
for (int i = 0; i < 8; i++) {
arr[i] = (int) ((Math.random() * 100) + 200);
}
         /*
向上面的数组再放100个,放【0,50】,打印输出
*/
// 先扩容
// 然后再给新的数组继续添加新的数据
// 输出数组
int arr2[] = new int[20];//1.先开辟一个20个元素的新数组
for (int i = 0; i < arr.length; i++) {
arr2[i]=arr[i];
System.out.print(arr2[i]+" ");
}
arr = arr2; //让arr指向新数组
//上面的部分可以用Arrays.copyOf(原数组,扩容后的长度)函数代替
//arr=Arrays.copyOf(arr,arr.length*2);//数组扩容 缩容的简单方法 要将新数组的地址指向原数组

for(int j=8;j<arr2.length;j++){
arr2[j]=(int)(Math.random()*50);
System.out.print(arr2[j]+" ");
}
 
System.out.println();
//Arrays.toString输出数组的内容
System.out.println(Arrays.toString(arr));// [ ,]的类型

数组的重置:

 

 

 

 数组的排序:Arrays.sort(数组名)

 

简单的线性查找:查找该数是否在数组中

复制代码
//线性查找,找到返回对应数的下标,找不到返回-1
    private static int linerSearch(int[] a, int i) {
        for(int j=0;j<a.length;j++){
            if(a[j]==i){
                return j;
            }
        }
        return -1;
    }
复制代码

练习2•:

/**
* 二分搜索算法
* 找出数组的中间值,将要比较的值与中间值进行比较
* 如果比中间值大,在中间值的右边找,将赋给a[mid]+1 反之在左边找
* 如果相等,直接打印找到了,返回mid下标
*/

 二分搜索:针对已经排好序的数组进行查找数组中的元素

复制代码
 private static int binarySearch(int[] a, int data) {
        int f=0;
        int l=a.length-1;
        while(f<=l) {
            int mid = (f + l) / 2;
            if(a[mid]==data){
                return mid;
            }
            else if(a[mid]>data){
               l=mid-1;    //把mid-1的下标赋给l
            }
            else{
                f=mid+1;
            }
        }
       return -1;
    }
复制代码

分析:

时间复杂度的分析:

 

 

 递归的方式:

复制代码
/**
     * 递归的二分搜索
     * @param a
     * @param i
     * @param j
     * @param data
     * @return
     */
    public static int binarySearch(int[] a,int i,int j,int data){
        int mid=(i+j)/2;
        if(i>j){
            return -1;
        }
        if(a[mid]==data){
            return mid;
        }
        if(a[mid]>data) {
            return binarySearch(a,i,mid-1,data);
        }
        else{
            return binarySearch(a,mid+1,j,data);
        }
    }
复制代码

练习3•:   斐波那契数列:1,1,2,3,5,8,13

 private static int fibonacci(int n) {
        if(n==1 ||n==2){

            return 1;
        }
        return  fibonacci(n-1) + fibonacci(n-2);  //返回n-1和第n-2项
    }

练习4:三角数组的最大值

/**
* 三角形数组求最大值问题,问题描述如下
* 12
* 8 9
* 11 7 16
* 13 9 8 7
*
* 从第一行的数字12开始选择数字,选择的方法是,向下、向左斜下方、
* 向右斜下方选择数字,问在每一行选择数字以后,得到的最大值是多少呢?
*/
int[][] arr = new int[4][];
        arr[0] = new int[]{12};
        arr[1] = new int[]{8,9};
        arr[2] = new int[]{11,7,16};
        arr[3] = new int[]{13,9,8,7};

        // 开辟记录最大值的辅助数组
        int[][] brr = new int[4][];
        for (int i = 0; i < brr.length; i++) {
            brr[i] = new int[i+1];
        }
        for(int i=0; i<4; ++i){
            brr[3][i] = arr[3][i];
        }

        // 循环arr数组
        for (int i = arr.length - 2; i >= 0; i--) {
            // 内层for循环再遍历每一行的元素值
            for (int j = arr[i].length - 1; j >= 0; j--) {
//                *//**
//         *                  arr[i][j]
//         * arr[i+1][j-1]    arr[i+1][j]    arr[i+1][j+1]
//         * max =>  brr[i][j]
//         *//*
                int r1=0,r2=0,r3=0;
                if(j > 0){
                    r1 = arr[i][j] + brr[i+1][j-1];
                }
                r2 = arr[i][j] + brr[i+1][j];
                r3 = arr[i][j] + brr[i+1][j+1];
                brr[i][j] = Math.max(r3, Math.max(r1,r2));
            }
        }
        System.out.println(brr[0][0]);
    }

 

 练习5:

/**在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照
从上到下递增的顺序排序,请完成一个函数,输入这样一个二维数组和一个整数,
2 5 7 8
4 6 9 10
5 8 10 15
判断数组中是否含有该整数。
*/
基本思想:先定义一个右上角的数,如果该数比它小,则列减减遍历该列左边的数;比它大则行加加,遍历该行下面的数;
public class FindNumber {
    public static void main(String[] args) {
        int[][] brray = {{2, 5, 7, 8}, {4, 6, 9, 10}, {5, 8, 10, 15}};
        System.out.println(find(brray, 10)); //true
        System.out.println(find(brray, 9));  //false
        System.out.println(find(brray, 20)); //true
    }
    //判断二维数组中是否有该元素
    public static boolean find(int brray[][],int target){
        //如果数组为空返回错误
        if(brray==null){
            return false;
        }
        //通过右上角(8)的数据判断
        int row=0; //
        int col=brray[0].length-1; //列的个数
        while (row<brray.length&&col>=0){
            if(target==brray[row][col]){
                return true;
            }else if(target>brray[row][col]){
                row++;
            }else{
                col--;
            }
        }
        return false;
    }
}

再写一下以左下角为基准的情况:

public static boolean find(int brray[][],int target){
if(brray==null){
            return false;
        }
        int col=0;
        int row=brray.length-1;
        while (row>=0&&col<brray.length){
            if(target==brray[row][col]){
                return true;
            }else if(target>brray[row][col]){
                col++;
            }else {
                row--;
            }
        }
   return false;
}

练习6:

/**

*在一个长度为n的数组并且数组中所有数字都在0~n-1的范围内,
*找出数组中任意一个重复的数字,要求时间复杂度为O(n),空间复杂度为O(1)

*/

 

/**在一个长度为n的数组并且数组中所有数字都在0~n-1的范围内,
 *找出数组中任意一个重复的数字,要求时间复杂度为O(n),空间复杂度为O(1)
 */

public class JudgeNumber {
    public static void main(String[] args) {
        int[] array={6,7,1,3,5,4,2,6};
        duplicate(array);
        int[] array1={1,1};//测试数据,注意题目要求,输入0~n-1之间的数
        duplicate(array1);
    }
    public static void duplicate(int[] array){
        if(array==null ||array.length<2){
            return;
        }
        /**
         *  遍历整个数组,当array[i]与i不相等时,一直遍历.
         *  6,7,1,3,5,4,2,6 开始只要0号位置上的值不相符,就一直交换数
         *  2,7,1,3,5,4,6,6
         *  1,7,2,3,5,4,6,6
         *  7,1,2,3,5,4,6,6
         *  6,1,2,3,5,4,6,7    array[i]==array[array[i]]  6等于6号位置的数吗? 等于就输出
         */
        for(int i=0;i<array.length;i++) {
            while (array[i]!=i) {
                if(array[i]==array[array[i]]){
                    System.out.println("任意一个重复数字为: "+array[i]);
                    return;
                } else {
                    int temp=array[i];
                    array[i]=array[temp];
                    array[temp]=temp;
                }
            }
        }
    }
}

 

 


 
posted @ 2019-09-21 11:18  acehm  阅读(257)  评论(0编辑  收藏  举报