数组

数组是什么

  • 数组就是用来存储一批同一类型数据的内存区域(可以理解成容器)

数组的定义

静态初始化数组

  • 定义数组的时候直接给数组赋值

静态初始化数组的格式

1
2
3
4
5
6
//        完整格式
// 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3……}
double[] score = {80.5, 90.0, 99.0, 88.5};
// 简化格式
// 数据类型[] 数组名 = {元素1,元素2,元素3……}
int[] age = {20,21,25};

动态初始化数组

  • 定义数组的时候只确定元素的类型和长度,之后再存入具体数据

动态初始化数组的格式

数组的基本原理

  • 首先再内存中开辟一块区域存放数组变量,等号右边new出来的对象也是一块区域(连续),存放12,24和36,该区域有自己的地址,等号从右向左执行,将地址交给数组变量进行存储,之后数组名根据地址去找数组对象

  • 注意:数组变量名中存储的是数组再内存中的地址,数组值引用类型

总结

两种数组定义时的特点和场景有什么区别

  • 当前已经直到存入数组的元素值,用静态初始化。
  • 当前不清楚要存入哪些数据,用动态初始化。
  • 两种格式的写法是独立的,不可以混用

数组的访问

  • 数组名称[索引]
    1
    2
    3
    4
    //        取值
    System.out.println(age[0]);
    // 赋值
    age[1]=20;
  • 数组的长度属性:length
    1
    System.out.println(age.length);

数组的几个注意事项

  • 什么类型的数组存放什么类型的数据,否则报错
  • 数组一旦被定义出来,程序执行的过程中,长度、类型就固定了

数组的遍历

数组遍历介绍

  • 遍历:就是一个一个数据的访问
  • 为什么要遍历?搜索、统计数据等等都要用到遍历

如何遍历数组

1
2
3
for (int i = 1; i < age.length; i++) {
System.out.println(age[i]);
}

数组的案例

数组遍历-求和

  • 某部门5名员工的销售额分别是:16、26、36、6、100,计算出他们的总销售额
    1
    2
    3
    4
    5
    6
    7
    //        某部门5名员工的销售额分别是:16、26、36、6、100,计算出他们的总销售额
    int[] ints = {16, 26, 36, 6, 100};
    int sum=0;
    for (int i = 0; i < ints.length; i++) {
    sum += ints[i];
    }
    System.out.println(sum);

数组遍历-求最值

1
2
3
4
5
6
7
8
int[] ints = {16, 26, 36, 6, 100};
int max = 0;
for (int i = 0; i <ints.length ; i++) {
if (ints[i] >max){
max = ints[i];
}
}
System.out.println(max);

数组遍历-猜数字游戏

  • 需求:随机生成1-20的5个数,猜数字
  • 未猜中提示:“未命中”,并继续猜测
  • 猜中提示:运气不错,猜对了,并输出该数据第一次出现的位置,且输出全部5个字,结束游戏
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Random random = new Random();
    int[] luckNumbers = new int[5];
    for (int i = 0; i < luckNumbers.length; i++) {
    int luckNumber = random.nextInt(20) + 1;
    luckNumbers[i] = luckNumber;
    }
    Scanner scanner = new Scanner(System.in);
    while (true) {
    System.out.println("请输入数字");
    int number = scanner.nextInt();
    for (int i = 0; i < luckNumbers.length; i++) {
    if (number == luckNumbers[i]) {
    System.out.println("运气不错,猜对了");
    System.out.println("该数据第一次出现的位置是:" + (i + 1));
    for (int j = 0; j < luckNumbers.length; j++) {
    System.out.print(luckNumbers[j]+" ");
    }
    return;
    }
    }
    System.out.println("未命中");
    }

数组遍历-排序

冒泡排序

  • 算法步骤:

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

  • 动画演示

  • 代码实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public static void main(String[] args) {
    int arr[] = {5,4,3,2,1};
    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+1];
    arr[j+1] = arr[j];
    arr[j] = temp;
    }
    }
    }
    for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
    }

冒泡排序的实现步骤

  • 定义一个外部循环控制总共需要冒几轮(数组的长度-1)
  • 定义一个内部循环,控制每轮依次往后比较几个位置(数组长度-i-1)

选择排序

  • 算法步骤:

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。

  • 动画演示:

  • 代码实现
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    int arr[] = {5,4,3,2,1};
    for (int i = 0; i < arr.length; i++) {
    int min=i;
    for (int j=i+1;j<arr.length; j++){
    if (arr[j] <arr[min]){
    min =j;
    }
    }
    if (i != min){
    int temp = arr[i];
    arr[i] = arr[min];
    arr[min] =temp;
    }
    }
    System.out.println(Arrays.toString(arr));

插入排序

  • 算法步骤:

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

  • 动画演示:

  • 代码实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int arr[] = {4,5,2,3,1};
for (int i = 1; i < arr.length; i++) {
for (int j=i-1;j>=0;j--){
if (arr[j]>arr[i]){
int temp=arr[j];
arr[j] =arr[i];
arr[i]=temp;
i=j-1;
}
else {
break;
}
}
}
System.out.println(Arrays.toString(arr));

快速排序

算法步骤

  • 1.从数列中挑出一个数据,成为”基准“(pivot);
  • 2.重新排序数列,所有元素比基准小的摆在基准前面,所有元素比基准大的摆在基准后面(相同的可以到任一边)。在这个分区退出后,该基准就处于数列的中间位置,这个成为分区(partition)操作。
  • 3.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

动画演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 public static void main(String[] args) {
int[] arr = {3, 2, 5, 4, 1};
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}

public static void quickSort(int[] arr,int low,int high){
// 方法退出条件,指针相遇或地位大于高位指针
if (low>=high){
return;
}
// 首先指定基准位和左右指针的记录位置
int pivot=arr[low];
int l=low;
int r=high;
int temp=0;
// 左指针小于右指针进行遍历
while (l<r){
// 先进行右边遍历
while (l<r && arr[r]>=pivot){
r--;
}
// 左边遍历
while (l<r && arr[l]<=pivot){
l++;
}
// 当l指针再r指针左侧(l<r),表示两指针还未相遇
if (l<r){
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
}
}
// 当左右指针相遇,则交换基准的位置
arr[low] = arr[l];
arr[l] = pivot;
// 在根据条件进行左边递归遍历
if (low<l){
quickSort(arr, low, l-1);
}
// 根据条件右边进行递归遍历
if (r<high){
quickSort(arr, r+1, high);
}
}

数组的内存图

java内存分配介绍

  • 方法区
  • 本地方法栈
  • 寄存器

数组的内存图

两个数组变量指向同一个数组对象