JAVA 数组
数组:
是一个容器 保存的是数据 保存相同数据类型的数据
数组定义
数据类型 [] 数组名 = 初值;
其中数据类型代表: 数组中盛放数据的 数据类型
举例:
声明一个整型数据
声明了长度为5的 整数数组
int[] array = new int[5];
注意: 数组的长度一旦给定 就不能修改
如何访问数组中的元素? 数组使用什么来保存数据?
数组使用下标(角标)来访问元素(保存元素) 下标从0开始
访问数组中的元素 数组名[下标]
System.out.println(array[5]);
// ArrayIndexOutOfBoundsException
数组下标越界异常
相当于 指向一个空
array = null;
// NullPointerException
空指针异常:访问一块不属于你的内存空间
数组的第二种声明方式
int[] array = new int[] {1, 2, 3, 4, 5};
获取数组的长度
int length = array.length;
System.out.println(length);
获取数组中每一个元素的值(遍历数组)
只要是数组 肯定要使用遍历
System.out.println(array[0]);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
变量在内存中的表现
数组定义
数组元素反转
(将数组中的值 倒过来) 操作原数组
分析:
1. 换 length /2 整数次
2. 第一数 和最后一个数 换 依次换....
array[0] 和 array[length - 1 - 0 ]
array[1] 和 array[length - 1 - 1 ]
. . .
. . .
. . .
array[i] 和 array[length - 1 - i ]
如何交换?
利用中间值交换
int a = 10;
int b = 15;
int c = 0;
c = a;
a = b;
b = c;
public static void main(String[] args) {
int[] array = new int[] { 1, 2, 3, 4, 5 };
// 这里做的是一个 地址的传递
reverse(array);
}
public static void reverse( int[]array) {
for (int i = 0; i < array.length / 2; i++) {
int temp = array[i];
array[i] = array[array.length - i - 1];
array[array.length - i - 1] = temp;
}
// 遍历数组的方法
System.out.println(Arrays.toString(array));
}
写一个交换两个整数的方法
public static void reverseNum(int a, int b) {
int temp = a;
a = b;
b = temp;
}
public static void main(String[] args) {
int x = 10;
int y = 5;
reverseNum(x, y);
System.out.println("x= "+ x + "y= "+ y);
}
数组反转
数组排序
冒泡排序
核心排序思想: 相邻两个数进行比较 然后交换位置
int[] array = new int[] { 3, 2, 5, 1 };
3 2 5 1
第一趟 比较 确定一个最大值 放在最后
第一次:2 3 5 1
第二次:2 3 5 1
第三次:2 3 1 5
第二趟
第一次:2 3 1 5
第二次:2 1 3 5
第三趟
第一次:1 2 3 5
举例:
public static void main(String[] args) {
int[] array = new int[] { 8, 4, 7, 3, 6, 2, 5, 1 };
// 1.把双层循环结构搭出来
// 外循环相当于 比较多少趟
// 内循环相当于 一趟比多少次
// 外循环 - 1 代表 5个数 比较 4趟 比较数组长度 - 1趟
for (int i = 0; i < array.length - 1; i++) {
// 注意内循环 - 1 防止数组越界
// 内循环 - i 每一趟都少比一次
for (int j = 0; j < array.length - 1 - i; j++) {
// 2.相邻 两个数 比较 交换
if (array[j] > array[j + 1]) {
// 交换
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
选择排序
排序核心思想: 选择一个数 依次和后面的数比较 换位
array[0] --- array[1] array[2] array[3]
array[1] --- array[2] array[3]
array[2] --- array[3]
举例:
public static void main(String[] args) {
int[] array = new int[] { 3, 2, 5, 1 };
// 1.写循环架构
// 外循环 -1 5个数比4趟 相当于比较长度 -1 趟
for (int i = 0; i < array.length - 1; i++) {
// 内循环 1 + i 把不需要比较去除 array[0] 和 array[0]
// 每一次确定一个数
for (int j = i + 1; j < array.length; j++) {
// 2.比较 交换
if (array[j] < array[i]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
折半查找(提高效率的查找)
前提: 数组中查找 查找这个数在数组中的角标
注意: 需要在有序的数组中 查找
举例:
1. 随机数 [1,100] 的数
2. 让用户输入一个数
3. 输入的这个数 和 随机出来的这个数 比较
4. 告诉用户 猜的 是大了 还是 小了
5. 循环猜 一直到 猜中为止
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 随机数
int num = (int)(Math.random() * 100 + 1);
// 提示用户输入
System.out.println("我随机了一个数 看你能不能猜到 请输入");
// 循环猜
while (true) {
// 循环接受输入的数
String string = scanner.nextLine();
// 字符串转数字
int newNum = Integer.parseInt(string);
// 比较是大了 还是小了
if (newNum > num) {
System.out.println("你猜的数有点大");
}else if (newNum < num) {
System.out.println("你猜的数有点小");
}else {
System.out.println("你猜中了");
break;
}
}
System.out.println("电脑随机数是 " + num );
}
举例:
查找 22的角标 在数组 {3,5,6,9,12,18,22,33} 中
public static void main(String[] args) {
int[] array = new int[] { 3, 5, 6, 9, 12, 18, 22, 33 };
// 把要用到变量 全部声明一遍
// 声明最大 最小 中间角标
int min = 0;
int max = array.length - 1;
int mid = (min + max) / 2;
// 要查找的值
int key = 1;
/*
* 循环查找
* array[mid] = key;
*/
while (key != array[mid]) {
// 比较 如果比中间角标大 挪动小角标
// 如果比中间角标小 挪动大角标
if (key > array[mid]) {
min = mid + 1 ;
}else if (key < array[mid]) {
max = mid - 1 ;
}
// 挪动完角标后 还要进行折半操作
mid = (min + max) / 2;
// 当最大角标 小于 最小角标的时候 说明数组中没有这个数
if (max < min) {
// 进到这里说明没这个数
mid = -1;
break;
}
}
System.out.println("这个数的角标是: "+ mid);
}