1)数组
介绍:数组可以存放多个 同一类型 的数据.数组是 引用类型.即:数组就是一组数据
1.1) 数组的使用
一. 数组的定义
- 动态初始化1
数据类型 数组名[]=new 数据类型[数组大小]
(或者 数据类型 []数组名=new 数据类型[数组大小])
示例:
int []day=new int[7];//创建了一个存放int类型的数组,数组名为day,数组大小为7
int mouth[]=new int[12];
- 动态初始化2
先声明数组:数据类型 数组名[]; 或者 数据类型[] 数组名;int day[];或 int[] a;(这时day是空值null)
后创建数组:数组名=new 数据类型[数组大小];
day=new int[7];(这时分配给day内存空间,可以存放数据) - 静态初始化
数据类型 数组名[]={元素值,元素值…}
示例:
int num[]={2,3,5,7,11,13,17,19};
二. 数组的引用(访问)
数组名[下标] 比如:我要使用day数组的第4个数据 day[3]
(数组的下标从0到数组大小-1)
三. 数组使用细节
- 数组创建后,如果没有赋值,有默认值:
0: int,short,byte,long
0.0: float,double
\u0000: char
false: boolean
null: String - 数组下标从0开始
- 数组下标越界程序异常,比如int [] year=new int[4];有效下标为0到3;
- 数组属于引用类型,数组型数据是对象
1.2) 数组赋值机制
数组在默认情况下是引用传递,赋的是地址的值,赋值方式为引用赋值(即 被赋值的数组变得与赋值数组指向同一内存空间)
示例
int num1[]={1,3,5,7,8,10,12};
int num2[]=num1;//将num1的地址赋给num2
num2[0]=100;//将100赋给num2的第一个元素
for(int i=0;i<num1.length;i++)
{
System.out.println(num1[i]);
}
结果:
100
3
5
7
8
10
12
1.2.1) 数组拷贝
作用:使得拷贝后的数组不影响原数组
示例:
int num1[]={1,3,5,7,8,10,12};
int num2[]=new int[num1.length];//给num2开辟和num1同样大的空间
for(int i=0;i<num1.length;i++)//遍历num1 将num1的每个元素赋给num2的每个元素
{
num2[i]=num1[i];
}
num2[0]=99;
System.out.println("num2");
for(int i=0;i<num1.length;i++)
{
System.out.println(num2[i]);
}
System.out.println("num1");
for(int i=0;i<num1.length;i++)
{
System.out.println(num1[i]);
}
num2
99
3
5
7
8
10
12
num1
1
3
5
7
8
10
12
1.2.2) 数组翻转
方法一:
int num1[]={1,3,5,7,8,10,12};
int temp=0;
for(int i=0;i<num1.length/2;i++)//顺数和倒数位数相同的元素进行交换,一共交换数组长/2次
{
temp=num1[num1.length-i-1];
num1[num1.length-i-1]=num1[i];
num1[i]=temp;
}
for(int i=0;i<num1.length;i++)
{
System.out.println(num1[i]);
}
结果:
12
10
8
7
5
3
1
方法二:
int[] day={4,6,9,11};
int[] day2=new int[day.length];
for(int i=day.length-1;i>=0;i--)//逆序遍历数组day将数组day中的每个元素拷贝到数组二
{
day2[day2.length-i-1]=day[i];
System.out.println(day2[day2.length-i-1]);
}
day=day2;//将day2的地址赋给day1 day1原来空间中的值没有被引用 会被当做垃圾销毁
System.out.println("day数组");
for(int i=0;i<day.length;i++)//逆序遍历数组day将数组day中的每个元素拷贝到数组二
{
System.out.println(day[i]);
}
结果:
11
9
6
4
day数组
11
9
6
4
1.2.3) 数组扩容
要求:
- 增加元素6放在数组最后
- 可以通过输入y/n判断是否继续添加元素
import java.util.Scanner;
public class xiafan {
public static void main(String[] args){
Scanner myscanner =new Scanner(System.in);
int []num={1,2,3,4,5};
do {
int []num2=new int[num.length+1];//建立一个能比num数组多储存一个元素的数组num2
for(int i=0;i<num.length;i++)//遍历num数组将num的元素赋给对应的num2
{
num2[i]=num[i];
}
System.out.println("请输入你要添加的元素");
int addnum=myscanner.nextInt();
num2[num2.length-1]=addnum;
num=num2;//将num2的地址赋给num,num原来储存的元素会被当成垃圾销毁
for(int i=0;i<num.length;i++)
{
System.out.println(num[i]);
}
System.out.println("是否继续添加y/n");//询问客户是否继续添加
char key= myscanner.next().charAt(0);
if(key=='n'){
break;
}
}while(true);
System.out.println("你退出了程序");
结果:
请输入你要添加的元素
9//9为输入的数据
1
2
3
4
5
9
是否继续添加y/n
n//n为输入的数据
你退出了程序
数组缩减与扩容类似,方法如下:
import java.util.Scanner;
public class xiafan {
public static void main(String[] args){
Scanner myscanner =new Scanner(System.in);
int []num={1,2,3,4,5};
do {
int []num2=new int[num.length-1];//建立一个能比num数组少储存一个元素的数组num2
for(int i=0;i<num.length-1;i++)//遍历num数组将num的元素赋给对应的num2
{
num2[i]=num[i];
}
num=num2;//将num2的地址赋给num,num原来储存的元素会被当成垃圾销毁
for(int i=0;i<num.length;i++)
{
System.out.println(num[i]);
}
System.out.println("是否继续缩减y/n");//询问客户是否继续缩减
char key= myscanner.next().charAt(0);
if(key=='n'){
break;
}
else
{
if (num.length==1){
System.out.println("无法再次缩减");
break;
}
}
}while(true);
System.out.println("你退出了程序");
结果:
1
2
3
4
是否继续缩减y/n
y
1
2
3
是否继续缩减y/n
y
1
2
是否继续缩减y/n
y
1
是否继续缩减y/n
y
无法再次缩减
你退出了程序
2)排序
- 分类:
- 内部排序:
将所有需要处理的数据加载到内部存储器进行排序(包括交换式排序法,选择式排序法,插入式排序法) - 外部排序:
数据量过大,无法全部加载到内存中,需借助外部存储进行排序(包括合并排序法,直接合并排序法)
- 基本思想:从下标较大元素开始,依次比较相邻元素,若发现逆序则交换,使值较大的元素从前向后移(或向前),就像水底的气泡向上冒(又称冒泡排序)
- 示例:
int num[]={11,13,2,7,3,5};
int temp=0;
for(int i=1;i<num.length;i++){//第i次循环确定第i大的数
for(int n=0;n<num.length-1;n++){//每次循环判断是否交换的次数减一
if(num[n]>num[n+1]){
temp=num[n];
num[n]=num[n+1];
num[n+1]=temp;
}
}
}
for(int i=0;i<num.length;i++){
System.out.println(num[i]);
}
结果
2
3
5
7
11
13
3)查找
- 分类
- 顺序查找 SeqSearch.java
- 二分查找(二分法,学算法时再详细讲解)
示例:
String[] names={"汉堡王","金拱门","肯德基","华莱士"};
Scanner myScanner=new Scanner(System.in);
System.out.println("请输入餐厅");
String eat = myScanner.next();
int index=-1;
for(int i=0;i<names.length;i++){
if(eat.equals(names[i])){
System.out.println("这就是 "+eat);
System.out.println("下标为= "+i);
index =i;
break;
}
}
if(index==-1){
System.out.println("很抱歉,找不到 "+eat);
}
结果:
请输入餐厅
星巴克
很抱歉,找不到 星巴克
4) 二维数组
介绍:二维数组相当于每个元素都是一维数组的一维数组
- 初始化:
int a[][]=new int[4][3];//创建类似4*3的矩阵的数组 未赋值的值默认为0
a[2][1]=14;
int b[][] = {{0, 0, 0,5},//已知少量有限数据时的初始化
{0, 9, 8},//每行的一维数组可以有不同的元素个数
{0, 0, 5,0,77}
};
int c[][];//先定义
c=new int[2][7];//后赋值
for(int i=0;i<a.length;i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j] + " ");
}
System.out.println();
}
System.out.println("数组个数="+b.length);//length可以获得二维数组行数
System.out.println("第3行第3个数="+b[2][2]);//要取第i行第j个数要输入[i-1][i-1]
for(int i=0;i<b.length;i++){
for(int j=0;j<b[i].length;j++){
System.out.print(b[i][j]+" ");
}
System.out.println();
}
for(int i=0;i<c.length;i++){
for(int j=0;j<c[i].length;j++){
System.out.print(c[i][j]+" ");
}
System.out.println();
}
结果:
0 0 0
0 0 0
0 14 0
0 0 0
数组个数=3
第3行第3个数=5
0 0 0 5
0 9 8
0 0 5 0 77
0 0 0 0 0 0 0
0 0 0 0 0 0 0
- 动态初始化 列数不确定:
int a[][]=new int[3][];//创建了一个名为a的三行?列的二维数组
for(int i=0;i<a.length;i++)
{
a[i]=new int[i+1];//如果没有给一维数组new,那么a[i]=null
for(int n=0;n<a[i].length;n++){
a[i][n]=i+1;
}
}
for(int i=0;i<a.length;i++){
for(int n=0;n<a[i].length;n++) {
System.out.print(a[i][n]+" ");
}
System.out.println();
}
结果:
1
2 2
3 3 3