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

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);
	}

}

在这里插入图片描述

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));
	}

}

在这里插入图片描述

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);
	}

}

在这里插入图片描述

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]);
	}

}

在这里插入图片描述

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) + "位同学是队长");
			}
		}
	}
}

在这里插入图片描述

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--;
	    }
	}
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昵称系统有问题

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值