【数组】复习与企业真题
目录
- 数组概述
- 一维数组的使用(重要)
- 二维数组的使用(难点)
- 数组的常用算法
- Araays工具类的使用
- 数组中的常见异常
- 企业真题
数组概述
- 数组,就可以理解为多个数据的组合
- 是程序中的容器:数组、集合框架(List、Set、Map)
- 数组存储的数据的特点:依次紧密排序的,有序的,可以重复的
- 此时的数组、集合框架都是在内存中对多个数据存储
- 数组的其他特点:一旦初始化,其长度就是确定的、不可更改的
一维数组的使用(重要)
-
数组的声明和初始化
int [] arr = new int[3];
int [] arr1 = new int[] {1,2,3}; -
调用数组指定元素:使用角标、索引、index
-
数组的属性:length表示数组的长度
-
数组的遍历
-
数组元素的默认初始化值
1)整型数组元素初始化值:0
2)浮点型数组元素初始化值:0.0
3)字符型数组元素初始化:0
4)boolean型数组元素初始化:false
- 引用数据类型数组元素默认值:null
- 一维数组的内存解析
前提;在main()中声明变量:int [] arr = new int []{1,2,3};
虚拟机栈:main()作为一个栈帧,压入栈空间中。在main()栈帧中,存储着arr变量。arr记录着数组实体的首地址值
堆:数组实体存储在堆空间中
二维数组的使用(难点)
- 二维数组:一维数组的元素,又是一个唯一数组,则构成二维数组
- 调用数组的指定元素
- 数组的属性:length,表示数组的长度
- 数组的遍历
- 数组元素默认初始化值
- 二维数组的内存解析
1)外层元素,默认存储地址值
2)内层元素:默认与一维数组元素的不同类型的默认值规定相同
数组的常用算法
- 数值型数组的特征值计算:最大值、最小值、总和、平均值等
- 数组元素的赋值。比如:杨辉三角
package ArrayTest;import java.util.ArrayList;
import java.util.List;
import java.util.Random;/*** 【数组的常见算法1】* 1、数值型数组特征值统计* 这里的特征涉及到:平均值、最大值、最小值、总和等** 2、数组的元素赋值*/public class TwoArrayOpeExer {/*** 案例:定义一个int类型的数组,包含10个元素,分别赋值一些随机整数,然后求出所有元素的最大值、最小值、总和,平均值,并输出来* 要求:所有随机数都是两位数:[10,99]* 提示:求[a,b]范围内的随机数:(int)(Math.random(b-a+1))+a;*/public static void main(String[] args) {//1.动态初始化方式创建数组int [] arr = new int[10];//2.通过循环给数组元素赋值for(int i=0;i< arr.length;i++){arr[i] = (int)(Math.random()*(99-10+1))+10;System.out.println(arr[i]);}//3.求最大值int max = arr[0];for(int i1=0;i1<arr.length;i1++){if(max<arr[i1]){max = arr[i1];}}System.out.println("最大值为:"+max);//4.求最小值int min = arr[0];for(int i2=0;i2< arr.length;i2++){if(min>arr[i2]){min=arr[i2];}}System.out.println("最小值为:"+min);//3.3 求总和、平均值int sum=0;for(int i=0;i< arr.length;i++){sum+=arr[i];}System.out.println("总和为"+sum);int avg = sum/arr.length;System.out.println("均值为"+avg);/*** 案例:评委打分* 分析以下需求,并用代码实现* (1)在编程竞技中,有10位评委为参赛的选手打分,分数分别为:5,4,6,8,9,0,1,2,7,3* (2)求选手的最后得分(去掉一个最高分和一个最低分后,其余8位评委打分的平均值)*/int arr1[] = new int[10];//(0,10)int sum1=0;int max1=arr1[0];int min1=arr1[0];for(int i=0;i< arr1.length;i++){int score = (int)(Math.random()*11);arr1[i]=score;sum1+=arr1[i];}for(int i =0;i<arr1.length;i++){if(arr1[i]>max1){max1=arr1[i];}if(arr1[i]<min1){min1=arr1[i];}}double result = (double) (sum1-min1-max1)/ (arr1.length-2);System.out.println(result);/*** 使用二维数组打印一个10行杨辉三角。* 提示:* 1* 1 1* 1 2 1* 1 3 3 1* 1 4 6 4 1*1、第一行有1个元素,第n行有n个元素*2、每一行的第一个元素和最后一个元素都是1* 3、从第三行开始,对于非第一个元素和最后一个元素。即:* yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];**///1.创建二维数组int [][] arr2 = new int[10][];//2.使用循环结构初始化外层数组元素for(int i=0;i< arr2.length;i++) {arr2[i] = new int[i + 1];//3.给数组的元素赋值//3.1给数组每行的首末元素赋值为1arr2[i][0] = 1;arr2[i][i] = 1;//3.2给数组每行的非首末元素赋值for (int j = 1; j < arr2[i].length - 1; j++) {arr2[i][j] = arr2[i - 1][j - 1] + arr2[i - 1][j];}}//遍历二维数组for(int i=0;i<arr2.length;i++){for(int j=0;j<arr2[i].length;j++){System.out.print(arr2[i][j]+"\t");}System.out.println();}/*** 创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且都是随机赋值。同时,要求元素的值各不相同*/Random random = new Random();List<Integer> list = new ArrayList<>();while(list.size()<6){int num = random.nextInt(30)+1;if(!list.contains(num)){list.add(num);}}System.out.println(list);/*** 案例:遍历扑克牌* 提示:使用两个字符串数组,分别保存花色和点数,再用一个字符串* Stirng [] hua = {"黑桃","红桃","梅花","方片"}* String [] dian = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}*/String [] hua = {"黑桃","红桃","梅花","方片"};String [] dian = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};String result1 [] = new String[hua.length* dian.length];int k=0;for(int i=0;i< hua.length;i++){for(int j=0;j< dian.length;j++){result1[k++]=hua[i]+dian[j];}}for(int i=0;i<result1.length;i++){System.out.print(result1[i]+ " ");if(i%13 == 12){System.out.println();}}}
}
- 数组的复制、赋值、反转、扩容、缩容
- 数组的查找
线性查找、二分法查找(前提:数组有序) - 数组的排序
冒泡排序:最简单
快速排序:最常用
package ArrayTest;public class ArrayExpr2 {/*** 【数组的常见算法2】* 1、数组的扩容与缩容* 2、数组元素的查找* 顺序查找:* 优点:算法简单* 缺点:执行效率低,执行的复杂度O(N)* 二分查找:* 优点:执行效率高,执行时间复杂度O(logN)* 缺点:算法相对于顺序查找难一点;数据必须是有序的** 3、数组的排序:通常来说,排序的目的是快速查找* 衡量排序算法的优势:* 时间复杂度:分析关键字比较次数和记录的移动次数* 空间复杂度:分析排序算法需要多少辅助内存* 稳定性:若两个记录A和B的关键字值相等,但排序后A\B的先后顺序保持不变,则称为这种顺序算法是稳定的。* 冒泡排序:时间复杂度(O(N^2))**** 快速排序:时间复杂度(O(nlogn))***/public static void main(String[] args) {/*** 案例1:数组的扩容* 现有数组 int [] arr = new int[]{1,2,3,4,5};* 先将数组的长度扩容1倍,并将10,20,30三个数据添加到arr数组中*/int [] arr = new int[]{1,2,3,4,5};//扩容1倍容量int [] newarr = new int[arr.length*2];//将原有数组中的元素赋值到新的数组中for(int i=0;i<arr.length;i++){newarr[i]=arr[i];}// 将10、20、30三个数据添加到数组中newarr[arr.length]=10;newarr[arr.length+1]=20;newarr[arr.length+2]=30;//将新的数组的地址赋值给原有的数组变量arr = newarr;for(int i=0;i<arr.length;i++){System.out.print(arr[i]+"\t");}System.out.println();/*** 案例2:数组的缩容* 现有数组 int[] arr={1,2,3,4,5,6,7}.现需删除数组中索引为4的元素*/int arr2 [] = new int[]{1,2,3,4,5,6,7};int deleteIndex = 4;int newarr2 [] = new int[arr2.length-1];for(int i=0;i<deleteIndex;i++){newarr2[i] = arr2[i];}for(int i=deleteIndex;i<arr2.length-1;i++){newarr2[i]=arr2[i+1];}arr2 = newarr2;for(int i=0;i<arr2.length;i++){System.out.print(arr2[i]+"\t");}System.out.println();/***线性查找* 定义数组:int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};* 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值*/boolean flag = true;int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};int target =5;for(int i=0;i<arr3.length;i++){if(target==arr3[i]){System.out.println(i);flag=false;break;}}if(flag){System.out.println("不好意思,没有找到此元素");}/*** 二分查找* 定义数组:int arr4 [] = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};* 查找元素5是否在上述数组中出现过?如果出现,输出对应的索引值。** 二分查找步骤:* 1、设定头部边界下标和尾部边界下标初始值 head=0,end=arr.length-1* 2.如果head<=end,计算中间元素下标mid=(head+end)/2* 如果value=arr[mid], true 找到了* 如果value>arr[mid] ,true 修改左边边界 head=mid+1* 如果value<arr[mid], true 修改右边边界 end=min-1*/int arr4 [] = new int[]{2,4,5,8,12,15,19,26,37,49,51,66,89,100};int head=0;int end=arr4.length-1;int target1 = 100;boolean is_flag=false;while(head<=end){int mid =(head+end)/2;if(target1==arr4[mid]){System.out.println("找到了"+target1+",对应的位置为,"+mid);is_flag=true;break;}else if(target1>arr4[mid]){head = mid+1;}else{end = mid-1;}}if(!is_flag){System.out.println("不好意思,未找到");}/*** 使用冒泡排序、实现整型数组元素的排序操作* 比如:int arr5[] = new int[]{34,54,3,2,65,7,34,5,76,34,67}*/int arr5[] = new int[]{34,54,3,2,65,7,34,5,76,34,67};//遍历for(int i=0;i<arr5.length;i++){System.out.print(arr5[i]+"\t");}//冒泡排序,实现数组元素从小到大排列for(int j=0;j<arr5.length-1;j++){for(int i=0;i<arr.length-j;i++){if(arr5[i]>arr5[i+1]){//交换arr5[i] 和 arr5[i+1]int temp = arr5[i];arr5[i] = arr5[i+1];arr5[i+1]=temp;}}}System.out.println();for(int i=0;i<arr5.length;i++){System.out.print(arr5[i]+"\t");}/****/}
}
Araays工具类的使用
toSring()/sort()/binarySearch()
数组中的常见异常
- ArrayIndexOutBoundsException(数组角标越界异常)
- NullPointerException(空指针异常)
package ArrayTest;
/*** 数组的使用中常见异常小结* >数组角标越界异常:ArrayIndexOutBoundsException* >空指针异常:NullPointerException**/import java.util.Arrays;public class ArraysTest {/*** 数组工具类Arrays的使用(熟悉)* 1、Arrays类所在位置:处在java.util包下* 2、作用:* java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索) 的各种方法。*/public static void main(String[] args) {//1.boolean equals(int[] a,int [] b);比较两个数组的元素是否依次相等int [] arr1 = new int[]{1,2,3,4,5};int [] arr2 = new int[]{1,2,3,4,5};boolean isEqual = Arrays.equals(arr1,arr2);System.out.println(isEqual);//2.String toString(int[] a):输出数组元素信息String result = Arrays.toString(arr1);System.out.println(result);//3.void fill(int[] a.int val):将制定值填充到数组中Arrays.fill(arr1,10);System.out.println(Arrays.toString(arr1));//4.void sort(int []a):使用快速跑徐算法实现的排序int [] arr3 = new int[]{34,54,3,2,65,7,34,5,76,34,67};Arrays.sort(arr3);System.out.println(Arrays.toString(arr3));//5. int binarySearch(int [] a,int key);二分查找//当返回的数值为复数,表示没找到//使用前提:当前数组必须是有序的int index = Arrays.binarySearch(arr3,5);if(index>0){System.out.println("找到了,索引位置为:"+index);}else{System.out.println("未找到");}//空指针异常
// int [] arr4 = new int [10];
// arr4=null;
// System.out.println(arr4[0]);//情况二int [][] arr5 = new int [3][];System.out.println(arr5[0][1]);}
}
企业真题
-
数组有没有length()这个方法?String有没有length()这个方法?
数组没有length(),是length属性
String有length() -
有数组int [] arr,用java代码将数组元素顺序颠倒
-
为什么数组要从0开始编号,而不是1
数组的索引表示数据元素距离首地址的偏移量。因为第一个元素的地址与首地址相同,所以偏移量就是0.所以从0开始 -
数组有什么排序的方式,手写一下
冒泡 -
常见排序算法,说一下快排的过程,时间复杂度?
-
二分算法实现数组的查找
-
怎么求数组的最大子序列和