Java从入门到实战总结-1.4、Java数组


文章目录

1、数组

(1)、概述

数组是相同数据类型的多个数据的容器。

这些元素按线性顺序排列。所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;除最后一个元素外,每一个元素都有唯一的后继元素。(“简单理解就是:一个跟一个顺序排列”)。

(2)、创建格式

格式 1. 数据类型[] 数组名称 = new 数据类型[数组长度];

格式 2. 数据类型[] 数组名称 = {数组内容 1,数组内容 2,数组内容 3…数组内容 n};

格式 3. 数据类型[] 数组名; 格式 3 属于只创建了数组引用名, 并未在内存创建数组空间。

格式 4. 数据类型[] 数组名称 = new 数据类型[]{内容 1,内容 2,内容 3…内容 n};

(3)、下标

可以理解为数组中内容的数字序号,从 0 开始 ,对于长度为 n 的数组,下标的范围是 0~n-1。

可以通过下标的方式访问数组中的每一个元素。

例如: 创建 int 类型数组 arr , 给数组 arr 的 5 下标赋值数据 , 然后打印

int[] arr = new int[10];

arr[5] = 123;

System.out.println(arr[5]);

(4)、数组长度获取

数组名称.length

(5)、注意

使用数组不当, 会出现如下问题:

  • 数组未赋值: 空指针异常
  • 超出长度的下标操作: 数组越界异常
  • 注意:数组的长度在创建时就固定了。

2、不常用数组定义格式

package day4;

public class Demo1 {

public static void main(String[] args) {
//数组不常用的创建方式
//1、创建数组,不初始化
int[] nums;
//2、创建数组,并制定数组中的内容
int[] ages = new int[] {10, 11, 12, 13, 14};

}

}

3、数组常见问题

1、数组下标越界问题,下标是从0开始计算的,下标最大值比数组长度要小1,比如长度是5,则下标是从0到4

2、空指针问题,当创建数组没有进行初始化时直接调用数组就会造成空指针问题

4、最大值最小值

利用中间变量存储后挨个比对确认即可

package day4;

public class Demo2 {

public static void main(String[] args) {
int[] nums = {10, 30 ,40, 33, 22, 20, 11, 13};
int max = nums[0],min = nums[0];

for(int i = 0; i < nums.length; i++) {
// max = max > nums[i] ? max:nums[i];
if(max < nums[i]) {
max = nums[i];
}
// min = min < nums[i] ? min:nums[i];
if(min > nums[i]) {
min = nums[i];
}
}
System.out.println("数组最大值:"+max+",最小值:"+min);
}

}

Java从入门到实战总结-1.4、Java数组_java

5、冒泡排序

(1)、原理

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

(2)、名字由来

是因为最小(或最大)的元素会经由交换慢慢“浮”到数列的顶端(降序或升序),就如同水中的气泡最终会上浮到顶端一样,故名“冒泡排序”。

(3)、升序排列的口诀

N个数字来排队

两两相比小靠前,

外层 循环length-1

内层循环length-i-1

(4)、降序排序的口诀

N个数字来排队

两两相比大靠前,

外层 循环length-1

内层循环length-i-1

关键总结(和之前打印直角三角形有类似之处):

  • 外层循环控制轮数(行数)
  • 内层循环控制每轮次数(列数)
package day4;

import java.util.Arrays;

public class Demo3 {

public static void main(String[] args) {
//冒泡排序,升序,大的值在右(降序比较判断时相反即可,大的值在左边)
int[] nums = {1, 2, 3, 6, 5, 4, 9, 8, 7};

for(int i = 0; i < nums.length - 1; i++) {
for(int j = 0; j < nums.length - 1 - i; j++) {
if(nums[j] > nums[j + 1]) {
int tmp = nums[j];
nums[j] = nums[j+1];
nums[j + 1] = tmp;
}
}
}

System.out.println(Arrays.toString(nums));
}

}

Java从入门到实战总结-1.4、Java数组_数组_02

6、二分查找

(1)、概述

二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,二分查找要求数组数据必须采用顺序存储结构有序排列。

(2)、原理

首先,假设数组中元素是按升序排列,将数组中间位置的数据与查找数据比较,如果两者相等,则查找成功;否则利用中间位置记录将数组分成前、后两个子数组,如果中间位置数据大于查找数据,则进一步查找前子数组,否则进一步查找后子数组。

重复以上过程,直到找到满足条件的数据,则表示查找成功,直到子数组不存在为止,表示查找不成功。

package day4;

import java.util.Arrays;
import java.util.Scanner;

public class Demo4 {

public static void main(String[] args) {
//二分查找,查找的数据必须有序排列的顺序结构
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
System.out.println("要搜索的数组:"+Arrays.toString(nums));

Scanner scanner = new Scanner(System.in);
System.out.println("请输入要在数组nums中查找的数据:");
int searchNum = scanner.nextInt();

//1、定义最小下标、最大下标、中间下标
int minIndex = 0;
int maxIndex = nums.length - 1;
int centerIndex = (minIndex + maxIndex)/2;
int i = 1;

while(true) {
System.out.println("查找次数:"+i);
//2、当中间值大于搜索值,说明要搜索值在左边,则最大下标更新中间下标减-1
//当中间值小于搜索值,则说明要搜索值在右边,最小值下标更新为中间下标+1
//相等时说明找到了直接退出搜索
if(nums[centerIndex] > searchNum) {
maxIndex = centerIndex - 1;
} else if(nums[centerIndex] < searchNum) {
minIndex = centerIndex + 1;
} else {
break;
}

//出现特殊情况一直搜索不到
if(minIndex > maxIndex) {
centerIndex = -1;
break;
}

//3、搜索一轮后根据最大和最小下标的更新再更新中间下标
centerIndex = (minIndex+maxIndex)/2;
i++;
}

System.out.println("要搜索的数据在数组中的位置:"+centerIndex);
}

}

Java从入门到实战总结-1.4、Java数组_数组_03

7、多维数组(了解)

可以简单理解为数组嵌套,每个数组指向的内容也是数组

创建格式:

数据类型 数组名 = new 数据类型[长度]

//int[][] 二维数组名称 = new int[外层数组长度][内层数组长度];
package day4;

public class Demo5 {

public static void main(String[] args) {
int[][] nums = new int[10][];

nums[0] = new int[] {1, 2, 3};

System.out.println(nums[0][2]);
}

}

Java从入门到实战总结-1.4、Java数组_i++_04

8、代码练习

1、今天同学们相约一起爬山游玩,为了更好的进行这场活动,大家准备推举 一个人作为出游的临时队长。为了体现合理公平,大家提出了一个比较有趣的规则。所有人围成一圈,顺序排号。从第一个人开始报数(从 1 到 3 报数), 凡报到 3 的人退出圈子,剩下的人继续报数,最后留下的当选为队长。 请你通过编写程序,求出一组人中的队长是原来第几位同学。

package day4;

import java.util.Scanner;

public class Homework10101006 {

public static void main(String[] args) {
//获取参与的同学人数
System.out.println("请输入参与人数:");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();

//将参与的同学编进一个布尔数组,全部赋值为true
boolean[] num = new boolean[n];
for (int i = 0; i < num.length; i++) {
num[i] = true;
}

int leftNum = n; // 剩余人数
int i = 0; // 报数
int index = 0; // 计数

//当剩余人数大于1时,循环报数,报到3的赋值为false,退出报数
while (leftNum > 1) {
if (num[index] == true) {
i++; // 开始报数
if (i == 3) {
num[index] = false;
i = 0; // 重新报数
leftNum--; // 剩余人数减一
}
}

index++;
if (index == n) {
index = 0;
}
}

//剩余为true的同学当选队长
for (int j = 0; j < num.length; j++) {
if (num[j] == true) {
System.out.println("第" + (j + 1) + "位同学是队长");
}
}
}
}

Java从入门到实战总结-1.4、Java数组_数组_05

2、逻辑及流程控制

1、查找某个整数
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。 然后将输
入一个整数,查找此整数,找到输出下标, 没找到给出提示。
2、找出数组的最值
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。输出数组
的最大值、最小值。
3、两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为
目标值的那两个整数,并输出他们的数组下标
假设每种输入只会对应一个答案,不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以输出 0,1
4、排序并查找
对数组{1,3,9,5,6,7,15,4,8}进行排序,然后使用二分查找 6 并
输出排序后的下标。
5、移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保
持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12] 输出: [1,3,12,0,0]
package day4;

import java.util.Arrays;
import java.util.Scanner;

public class Homework10101007 {

/**
* 1、查找某个整数
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。 然后将输
入一个整数,查找此整数,找到输出下标, 没找到给出提示。
2、找出数组的最值
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。输出数组
的最大值、最小值。
3、两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为
目标值的那两个整数,并输出他们的数组下标
假设每种输入只会对应一个答案,不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以输出 0,1
4、排序并查找
对数组{1,3,9,5,6,7,15,4,8}进行排序,然后使用二分查找 6 并
输出排序后的下标。
5、移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保
持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12] 输出: [1,3,12,0,0]
*/
public static void main(String[] args) {
//1、查找某个整数
findIntNum();

//2、找到数组的最值
findMaxMin();

//3、两数之和
System.out.println("两数之和:");
int[] nums = new int[] {2, 7, 11, 15};
int target = 9;
System.out.println(Arrays.toString(twoSum(nums, target)));

//4、排序并查找
System.out.println("对特定数组的排序后查找到序号为:"+sortFindIndex());

//5、移动零
int[] nums2 = new int[]{0,1,0,3,12};
System.out.println("移动零前的数组"+Arrays.toString(nums2));
moveZeroes(nums2);
System.out.println("移动零并排序后的数组"+Arrays.toString(nums2));
}

/**
* 冒泡排序,升序
*/
public static void sort(int[] nums) {
//排序
for(int i = 0; i < nums.length - 1; i++) {
for(int j = 0; j < nums.length - 1 - i; j++) {
if(nums[j] > nums[j + 1]) {
int tmp = nums[j];
nums[j] = nums[j+1];
nums[j + 1] = tmp;
}
}
}
}

/**
* 二分查找
* 返回值:未找到返回-1,找到返回对应数组中的序号
*/
public static int midSearch(int[] nums, int searchNum) {
int minIndex = 0;
int maxIndex = nums.length - 1;
int centerIndex = (minIndex + maxIndex)/2;
int i = 1;

while(true) {
if(nums[centerIndex] > searchNum) {
maxIndex = centerIndex - 1;
} else if(nums[centerIndex] < searchNum) {
minIndex = centerIndex + 1;
} else {
break;
}

if(minIndex > maxIndex) {
centerIndex = -1;
break;
}

centerIndex = (minIndex+maxIndex)/2;
i++;
}

return centerIndex;
}

/**
* 1、查找某个整数
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。 然后将输
入一个整数,查找此整数,找到输出下标, 没找到给出提示。
*/
public static void findIntNum() {
int[] nums = new int[10];
Scanner scanner = new Scanner(System.in);
System.out.println("请连续输入10个数用于查找:");
for(int i = 0; i < 10; i++) {
nums[i] = scanner.nextInt();
}

sort(nums);

System.out.println("请输入要在数组nums中查找的数据:");
int searchNum = scanner.nextInt();

int res = midSearch(nums, searchNum);

if(res == -1) {
System.out.println("未找到要搜索的值");
return ;
}
System.out.println("要搜索的数据在数组中的位置:"+res);
}

/**
*2、找出数组的最值
定义一个长度为 10 的整型数组 nums ,循环输入 10 个整数。输出数组
的最大值、最小值。
*/
public static void findMaxMin() {
int[] nums = new int[10];
Scanner scanner = new Scanner(System.in);
System.out.println("请连续输入10个整数组成数组:");
for(int i = 0; i < 10; i++) {
nums[i] = scanner.nextInt();
}

int max = nums[0],min = nums[0];
for(int i = 0; i < nums.length; i++) {
if(max < nums[i]) {
max = nums[i];
}
if(min > nums[i]) {
min = nums[i];
}
}
System.out.println("数组最大值:"+max+",最小值:"+min);
}

/**
* 3、两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为
目标值的那两个整数,并输出他们的数组下标
假设每种输入只会对应一个答案,不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以输出 0,1
*/
public static int[] twoSum(int[] nums, int target) {
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if (nums[j] == target - nums[i]) {
return new int[] {i, j};
}
}
}
return new int[]{0,0};
}

/**
* 4、排序并查找
对数组{1,3,9,5,6,7,15,4,8}进行排序,然后使用二分查找 6 并
输出排序后的下标。
*/
public static int sortFindIndex() {
int[] nums = new int[]{1, 3, 9, 5, 6, 7, 15, 4, 8};
sort(nums);
return midSearch(nums, 6);
}

/**
* 5、移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保
持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12] 输出: [1,3,12,0,0]
*/
public static void moveZeroes(int[] nums) {
int curIndex = nums.length - 1;
int lastIndex = nums.length - 1;
int count = 0;

while(curIndex >= 0) {
if (nums[curIndex] == 0) {
count = lastIndex - curIndex;
for (int i = 0; i < count; i++) {
nums[curIndex + i] = nums[curIndex + i + 1];
}
nums[lastIndex] = 0;
lastIndex--;
}
curIndex--;
}
}
}

Java从入门到实战总结-1.4、Java数组_i++_06