第三章 数组
3.1 数组的概述
- 数组的概念
- 数组名
- 下标或索引
- 元素
- 数组的长度
- 数组的定义:
数组(Array) 是多个同类型的数据按照一定顺序排列的,并使用 一个名字命名并通过编号的方式对这些数据进行统一的管理. - 数组的特点
- 数组是有序排列的
- 数组属于引用数据类型的变量,数组的元素,既可以是基本数据类型,又可以是引用数据类型
- 创建数组对象会在内存中开辟一整块连续的空间
- 数组的长度一单确定,就不能更改
- 数组的分类
- 按照维数,一维数组,二维数组…
- 按照数组元素的类型,基本数据类型的数组、引用数据类型的数组
3.2 一维数组的使用
- 一维数组的声明和初始化
int[] ids;//声明
ids = new int[]{10001,1002,1003,1004};
//静态初始化
String[] names = new String[2];//动态初始化
//错误的写法
//int[] arr1 = new int[];
//int[5] arr2 = new int[5];
//int[] arr3 = new int[3]{1,2,3};
//总结:
- 遍历数组
int[] ids;//声明
ids = new int[]{10001,1002,1003,1004};
for(int i = 0; i < ids.length;i++){
....
}
//foreach用法
for(int arr: ids){
System.out.println(arr);
}
- 二位数组输出杨辉三角
public class YangHuiTest{
public static void main(String[] args){
int yangHui[][] = new int[10][];
for(int i = 0;i<yangHui.length;i++){
yangHui[i] = new int[i + 1];
yangHui[i][0] = yangHui[i][i] = 1;
for(int j = 1; j <yangHui[i].length - 1 ;j++){
yangHui[i][j] = yangHui[i - 1][j - 1] + yangHui[i - 1][j];
}
}
//能不能用foreach遍历?
for(int i = 0;i < yangHui.length; i++){
for(int j = 0;j < yangHui[i].length;j++){
System.out.print(yangHui[i][j] + " ");
}
System.out.println();
}
//foreach用法
for(int[] out :yangHui ){
for(int inside:out){
System.out.print(inside +" ");
}
System.out.println();
}
}
}
- 数组中常见的算法
- 数组元素的赋值
杨辉三角、回形数等 - 求数值型数组中的最大值,最小值,平均值,总和
public class RandomTest {
public static void main(String[] args){
int[] arr = new int[10];
for(int i = 0; i < arr.length;i++){
arr[i] = (int)(Math.random() * 100 - 1 + 10);
System.out.print(arr[i] +"\t");
}
System.out.println();
//求数组的最大值
int maxValue = arr[0];
for(int x : arr){
if(maxValue < x){
maxValue =x;
}
}
System.out.println("最大值为:" + maxValue);
//求最小值
int minValue = arr[0];
for(int x : arr){
if(minValue > x){
minValue =x;
}
}
System.out.println("最小值为:" + minValue);
double sum = 0.0d;
for(int x : arr){
sum += x;
}
double ave = sum / arr.length;
System.out.println("总和为:" + sum);
System.out.println("平均值:" + ave);
}
}
- 数组的复制、反转(线性查找,二分查找)
String[] arr = new String[]{"AA","BB","CC","DD","EE"};
//数组的复制
String[] arr1 = new String[arr.length];
for(int i = 0;i < arr1.length;i++){
arr1[i] = arr[i];
System.out.println(arr[i]);
}
//数组的反转
for(int i = 0;i < arr.length / 2;i++){
String temp = arr[i];
arr[i] = arr[arr.length - 1];
arr[arr.length - 1] = temp;
}
//线性查找
String dest = "BB";
boolean isFlag = true;
for(int i = 0;i < arr.length;i++){
if(dest.equals(arr[i])){
System.out.println("指定元素的索引位置为" + i);
isFlag = false;
break;
}
}
if(isFlag){
System.out.println("没有找到");
}
- 数组元素的排序算法
- 冒泡排序
升级版的双向冒泡(鸡尾酒排序法)点击查看
//冒泡排序
int[] arr = new int[]{43,56,45,78,-12,21,-98,0,12,19};
for(int i = 0;i < arr.length - 1;i++){
for(int j = 0;j < arr.length - i - 1;j++){
if(arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
- 快速排序
public static int[] qsort(int arr[],int start,int end) {
int pivot = arr[start];
int i = start;
int j = end;
while (i<j) {
while ((i<j)&&(arr[j]>pivot)) {
j--;
}
while ((i<j)&&(arr[i]<pivot)) {
i++;
}
if ((arr[i]==arr[j])&&(i<j)) {
i++;
} else {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
if (i-1>start) arr=qsort(arr,start,i-1);
if (j+1<end) arr=qsort(arr,j+1,end);
return (arr);
}
public static void main(String[] args) {
int arr[] = new int[]{3,3,3,7,9,122344,4656,34,34,4656,5,6,7,8,9,343,57765,23,12321};
int len = arr.length-1;
arr=qsort(arr,0,len);
for (int i:arr) {
System.out.print(i+"\t");
}
}
/*//方式二*/
更高效点的代码:(TextendsComparable和SortUtil都是自己封装的类,里面重写和实现了compareTo和swap方法)
public <TextendsComparable<?superT>>
T[] quickSort(T[] targetArr,int start,int end){
inti=start+1,j=end;
T key=targetArr[start];
SortUtil<T> sUtil=new SortUtil<T>();
if(start==end)return(targetArr);
/*从i++和j--两个方向搜索不满足条件的值并交换
*
*条件为:i++方向小于key,j--方向大于key
*/
while(true){
while(targetArr[j].compareTo(key)>0)j--;
while(targetArr[i].compareTo(key)<0&&i<j)i++;
if(i>=j)break;
sUtil.swap(targetArr,i,j);
if(targetArr[i]==key){
j--;
}else{
i++;
}
}
/*关键数据放到‘中间’*/
sUtil.swap(targetArr,start,j);
if(start<i-1){
this.quickSort(targetArr,start,i-1);
}
if(j+1<end){
this.quickSort(targetArr,j+1,end);
}
returntargetArr;
}
/*//方式三:减少交换次数,提高效率/*/
private<TextendsComparable<?superT>>
voidquickSort(T[]targetArr,intstart,intend){
inti=start,j=end;
Tkey=targetArr[start];
while(i<j){
/*按j--方向遍历目标数组,直到比key小的值为止*/
while(j>i&&targetArr[j].compareTo(key)>=0){
j--;
}
if(i<j){
/*targetArr[i]已经保存在key中,可将后面的数填入*/
targetArr[i]=targetArr[j];
i++;
}
/*按i++方向遍历目标数组,直到比key大的值为止*/
while(i<j&&targetArr[i].compareTo(key)<=0){
/*此处一定要小于等于零,假设数组之内有一亿个1,0交替出现的话,而key的值又恰巧是1的话,那么这个小 于等于的作用就会使下面的if语句少执行一亿次。*/
i++;
}
if(i<j){
/*targetArr[j]已保存在targetArr[i]中,可将前面的值填入*/
targetArr[j]=targetArr[i];
j--;
}
}
/*此时i==j*/
targetArr[i]=key;//应加判断
/*递归调用,把key前面的完成排序*/
this.quickSort(targetArr,start,i-1);
/*递归调用,把key后面的完成排序*/
this.quickSort(targetArr,j+1,end);
//两个递归应加判
3.3 Arrays 工具类的使用
方法 | 作用 |
boolean equals(int[] a,int[] b) | 判断两个数组是否相等 |
String toString(int[] a) | 输出数组信息 |
void fill(int[] a,int val) | 用指定值填充数组 |
void sort(int[] a) | 对数组排序 |
int binarySearch(int[] a,int key) | 堆排序后的数组进行二分法检索指定的值 |
数组常见异常
1.数组角标越界:ArrayIndexOutOfBoundsException
2.空指针异常:NullPointerException