数组是相同类型数据的有序结合。数组描述的是相同类型的若干类型,按照一定的先后顺序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下标)来访问他其元素。
数组的特征:
* 1.定义数组必须指定大小
* 2.数组的每一个元素的内存都是连续的
* 3.数组的随机访问操作,是一个常量时间 arr[index]
* 4.每一个数组都内置了一个成员变量 length,表示数组的总长度
* 5.数组增加元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的时间是线性时间
* 6.数组删除元素,涉及增加位置后面的所有元素都要进行移动,所以该操作花费的是时间线性时间
* 7.数组的元素查找花费时间为线性时间,逐个遍历
练习1•:定义数组一个长度为100的数组,每一个随机数在100-200之间,每5个换行输出该数组
// 输出数组方式一 标准for循环(常用)
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
System.out.print(arr[i] + " ");
}
}
System.out.println();
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 比较两个数组的内容是否相等
数组的重置:
数组的排序: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; } } } } }