Java 之数组
一、一维数组的初始化
int[] array = {1,2,3,4,5}; // 数组大小为5的整型数组(这是Java语言的写法)
// 也可以这样表示
int array[] = {1,2,3,4,5}; //这样写会报一个warning:C-style array declaration of local variable 'array'。
// 这是C语言风格的写法
int array[] = {}; // 语法正确:但不能给元素赋初值,因为数组的大小为0
关于数组大小和默认值:
1.创建数组后不能再修改数组的大小。
2.基本数据类型的数组的默认值为0。
3.char型数组元素的默认值为/u0000。
4.布尔类型的数组的默认值为false。
二、动态赋值一维数组
语法:
数据类型[] 数组名 = new 数据类型[数组大小];
例如:
public class Main{
public static void main(String[] args){
final int N = 100; // 常量,表示数组的大小
int[] array = new int[N];
// 也可以直接这样表示
// int[] array = new int[100];
}
}
三、数组操作-数组的查找、插入与删除
3.1 查找
3.1.1 直接查找
时间复杂度:
O
(
N
)
O(N)
O(N)
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int[] array = new int[10];
for(int i=0;i<array.length;i++) array[i] = input.nextInt(); // 输入10个数字
int num = input.nextInt(); // 要查找的数字
boolean flag=false; // 判断是否查找到
for (int i=0;i<array.length;i++)
{
if(array[i]==num) // 查找到
{
flag=true;
System.out.println("要查找的数字的下标为:" + i);
}
}
if(!flag) System.out.println("没有找到!"); // 没有找到
}
}
3.1.2 二分查找
基本原理:
先对数组进行从小到大排序,然后将要查找的元素(key)与数组的中间元素比较。
1.如果key小于中间元素,只需要在数组的前一半元素中继续查找。
2.如果key和中间元素相等,匹配成功,查找结束。
3.如果key大于中间元素,只需要在数组的后一半元素中继续查找key。
时间复杂度: O ( l o g N ) O(logN) O(logN)
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
// 方便起见,直接初始化数组
int[] array = {0,12,25,33,45,56,69,72,81,99,123}; // 有序
int num = input.nextInt(); // 要查找的数字
int low = 0; // 下界
int high = array.length - 1; // 上界
boolean flag = false; // 判断是否找到
while (high>=low)
{
int mid = (low + high) / 2; // 中间元素
if(num< array[mid]) high = mid - 1;
else if(num>array[mid]) low = mid + 1;
else
{
System.out.println("找到了数字" + num + ",数字的下标为:" + mid);
flag=true;
break;
}
}
if(!flag) System.out.println("没有找到数字" + num);
}
}
*3.2 插入
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
// 插入一个数字
// 要想完成插入操作,数组的大小必须大于未插入时的大小
int[] array = new int[11]; // 比如我输入10个数字,插入1个数字,这样数组要开11
// 输入10个数字
System.out.println("请输入10个数字:");
for(int i=0;i<10;i++) array[i] = input.nextInt(); // 输入n-1个数字
System.out.print("请输入要插入的数字:");
int num = input.nextInt(); // 要插入的数字
System.out.print("请输入要插入位置的数字(插入在这个数字的后面):");
int k = input.nextInt(); // 要插入的位置(找到这个数字,然后插入到这个数字的后面)
int index = -1;
for(int i=0;i<10;i++)
{
if(k==array[i])
{
index=i;
break;
}
}
if(index==-1)
{
System.out.println("没有找到数字,系统不知道插入在什么位置!");
System.exit(0);
}
// 插入操作
for(int i=10-1;i>index;i--) array[i+1] = array[i];
array[index+1]=num;
// 输出插入结果
for (int i = 0; i < array.length; i++) System.out.print(array[i] + " ");
}
}
也可以插入到最后面,然后重新排序
*3.3 删除
3.3.1 直接遍历查找然后删除
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
// 方便起见,直接初始化数组
// 先查找一个数,然后将这个数字删除,后面的数字覆盖前面的数字
int[] array = {100,12,25,133,45,156,69,72,81,99,123}; // 有序
int num = input.nextInt(); // 要删除的数字
boolean flag = false; // 判断是否找到
int index = -1; // 要查找(删除)的数字的下标
for(int i=0;i< array.length;i++)
{
if(array[i]==num)
{
index=i;
flag=true;
break;
}
}
if(!flag)
{
System.out.println("没有找到数字" + num);
System.exit(0); // 没有找到就退出程序
}
// 将前面的元素用后面的元素覆盖
for(int i=index;i<array.length-1;i++) array[i]=array[i+1];
// 打印删除后的结果
for(int i=0;i<array.length-1;i++) System.out.print(array[i] + " ");
}
}
3.3.2 先二分查找后删除
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
// 方便起见,直接初始化数组
// 先查找一个数,然后将这个数字删除,后面的数字覆盖前面的数字
int[] array = {0,12,25,33,45,56,69,72,81,99,123}; // 有序
int num = input.nextInt(); // 要查找的数字
int low = 0; // 下界
int high = array.length - 1; // 上界
boolean flag = false; // 判断是否找到
int index = -1; // 要查找(删除)的数字的下标
while (high>=low)
{
int mid = (low + high) / 2; // 中间元素
if(num< array[mid]) high = mid - 1;
else if(num>array[mid]) low = mid + 1;
else
{
System.out.println("找到了数字" + num + ",数字的下标为:" + mid);
index=mid;
flag=true;
break;
}
}
if(!flag)
{
System.out.println("没有找到数字" + num);
System.exit(0); // 没有找到就退出程序
}
// 将前面的元素用后面的元素覆盖
for(int i=index;i<array.length-1;i++) array[i]=array[i+1];
// 打印删除后的结果
for(int i=0;i<array.length-1;i++) System.out.print(array[i] + " ");
}
}
数组定义后,数组的大小是没办法改变的。所以只能表现的看起来像删除或插入了。
四、数组应用实例
4.1
输入五个学生的成绩,求五个同学的平均成绩。
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
final int N = 5; // 数组大小
double[] grade = new double[N];
// 也可以写成这样:double[] grade = new double[5];
// 这样就不用定义常量N了
double sum=0; // 五个人成绩的和
for(int i=0;i<grade.length;i++)
{
grade[i] = input.nextDouble();
sum += grade[i];
}
System.out.println(sum/grade.length);
}
}
4.2
斐波那契数列,求前15位斐波那契数列的数值,并且求前15位的和,和平均值。
package com.company;
public class Main{
public static void main(String[] args){
int[] f = new int[16]; // 第一位是0,从1-15存放元素,所以数组大小为16
f[0]=0;
f[1]=1;
for(int i=2;i<=15;i++)
f[i]=f[i-1]+f[i-2];
System.out.println("输出结果为:");
int sum=0; // 和
for (int i=1;i<=15;i++)
{
System.out.print(f[i] + " ");
sum+=f[i];
}
int avg = sum/15; //平均值
System.out.println("\n前15位的和为:" + sum);
System.out.println("前15位的平均值位:" + avg);
}
}
/*
输出结果为:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
前15位的和为:1596
前15位的平均值位:106
*/
4.3
求数组中的最大值和最小值。随机生成10个0~1000的随机数,求最大值和最小值。
package com.company;
public class Main{
public static void main(String[] args){
int[] num = new int[10];
for(int i=0;i< num.length;i++)
{
num[i] = ((int) (Math.random() * 10000)) % 1001; // 随机生成0~1000的随机数
}
int max=num[0]; // 最大值
int min=num[0]; // 最小值
for (int i=1;i<num.length;i++)
{
if(num[i]>max) max=num[i];
if(num[i]<min) min=num[i];
}
System.out.println("数组中最大的数字为:" + max);
System.out.println("数组中最小的数字为:" + min);
}
}
4.4
定义一个整型数组,赋值后求出奇数个数和偶数个数。输入10个数字,求奇数的个数和偶数的个数。
package com.company;
public class Main{
public static void main(String[] args){
int[] num = new int[10];
// 随机生成数字
// for(int i=0;i< num.length;i++) num[i] = ((int) (Math.random() * 10000)) % 1001; // 随机生成0~1000的随机数
for(int i=0;i< num.length;i++) num[i] = input.nextInt(); // 输入十个数字
int cnt=0; // 奇数个数
int ans=0; // 偶数个数
for(int i=0;i<num.length;i++)
{
if(num[i]%2==1) cnt++;
else ans++;
}
System.out.println("数组中奇数的个数为:" + cnt);
System.out.println("数组中偶数的个数为:" + ans);
}
}
// 随机生成的数还挺有特点的,当生成数组足够多时,奇数和偶数趋近于各占一半,就像抛硬币一样hh。
4.5
随机生成1000个数字,查找输入数字在数组中的下标,如果查找到了输出在数组中的下标,如果没查找到输出-1。
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
int[] num = new int[1000];
for(int i=0;i< num.length;i++)
{
num[i] = ((int) (Math.random() * 10000)) % 1001; // 随机生成0~1000的随机数
}
// 输入要查找的数字
int n = input.nextInt();
int ans = -1; // 数组的下标,-1为没有找到
for(int i=0;i<num.length;i++)
{
if(num[i]==n)
{
ans=i;
break;
}
}
if(ans==-1) System.out.println("没有找到要查找的元素:" + ans);
else System.out.println("要查找的数字的下标为:" + ans);
}
}
五、二维数组
语法:
数据类型[][] 数组名 = new 数据类型[数组大小][数组大小];
// 例如:
int[][] a = new int[3][4];
double[][] b = new double[2356][423];
int[][] c = new int[][10];
// 注意:行是可以省略的,但是列不能省略
实例:输入三个人的语文、数学、英语成绩,并打印
package com.company;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String[] name = {"张三","李四","王五"}; // 学生姓名
String[] course = {"语文","数学","英语"}; // 学科名称
int[][] grade = new int[3][3]; // 分数
int len1 = name.length; // 学生个数
int len2 = course.length; // 科目个数
for (int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
System.out.print("请输入" + name[i] + "的" + course[j] + "成绩:");
grade[i][j] = input.nextInt();
}
}
System.out.println("\t\t语文\t\t数学\t\t英语");
for(int i=0;i<len1;i++)
{
System.out.print(name[i] + "\t\t");
for(int j=0;j<len2;j++) System.out.print(grade[i][j] + "\t\t");
System.out.print("\n");
}
}
}
运行结果:
总结:
数组是可以在内存中连续存储多个元素的结构。数组中的所有元素必须属于相同的数据类型。
数组必须先声明,然后才能使用。声明一个数组只是为该数组留出内存空间,并不会为其赋任何值。
数组的元素通过下标访问。
一维数组可以用一个循环动态初始化,而二维数组可用嵌套循环动态初始化。
二维数组可以看作是由一维数组的嵌套而构成的。