数组
- 为什么需要数组? 数组的引入,传统方法解决问题不灵活
// 数组的引出
// 如果有600只鸡,需要定义600多个变量,用传统方法虽然可以解决,但是没有灵活性
public class Array01{
public static void main(String[] args) {
/*
一个养鸡场有 6 只鸡,它们的体重分别是 3kg,5kg,1kg,3.4kg,2kg,50kg 。
请问这六只鸡的总体重是多少? 平均体重是多少? 请你编一个程序。
思路分析:定义6个变量
平均体重是: 总体重 / 6
*/
double hen1 = 3;
double hen2 = 5;
double hen3 = 1;
double hen4 = 3.4;
double hen5 = 2;
double hen6 = 50;
double totalWeight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
double avgWeight = totalWeight / 6;
System.out.println("总体重:" + totalWeight + " 平均体重:" + avgWeight);
}
}
- 数组介绍
数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型 - 数组快速入门
// 数组的引出
// 如果有600只鸡,需要定义600多个变量,用传统方法虽然可以解决,但是没有灵活性
public class Array01{
public static void main(String[] args) {
/*
一个养鸡场有 6 只鸡,它们的体重分别是 3kg,5kg,1kg,3.4kg,2kg,50kg 。
请问这六只鸡的总体重是多少? 平均体重是多少? 请你编一个程序。
思路分析:定义6个变量
平均体重是: 总体重 / 6
*/
// double hen1 = 3;
// double hen2 = 5;
// double hen3 = 1;
// double hen4 = 3.4;
// double hen5 = 2;
// double hen6 = 50;
// double totalWeight = hen1 + hen2 + hen3 + hen4 + hen5 + hen6;
// double avgWeight = totalWeight / 6;
// System.out.println("总体重:" + totalWeight + " 平均体重:" + avgWeight);
// 比如,我们用数组来解决一个问题
// 定义一个数组
// double[] 是double类型的数组,数组名是hens
// {3, 5, 1, 3.4, 2, 50};表示数组的值/元素
//
double[] hens = {3, 5, 1, 3.4, 2, 50, 7.8, 8.0};
// 遍历数组得到数组所有元素
// 1、我们可以通过hens[下标]来访问数组的元素
// 比如:下标是从0开始编号的,比如第一个元素是hens[0]
// 2.我们可以for循环,访问数组的所有的元素和值
// 3.使用一个变量 totalWeight 就可以累计所有的值
System.out.println("数组的长度:" + hens.length);
double totalWeight = 0;
for(int i = 0; i < hens.length; i++){
System.out.println("第"+ i + "个元素的值为:" + hens[i]);
totalWeight += hens[i];
}
System.out.println("总体重:" + totalWeight + " 平均体重:" + (totalWeight / hens.length));
}
}
- 数组的使用
import java.util.Scanner;
public class Array02{
public static void main(String[] args) {
//循环输入 5 个成绩,保存到 double 数组,并输出
double scores[] = new double[5];
System.out.println("循环输入5个成绩");
Scanner myScanner = new Scanner(System.in);
for (int i = 0; i < scores.length; i++){
System.out.println("请输入第" + (i + 1) + "个数字:");
scores[i] = myScanner.nextDouble();
}
System.out.println("循环输出5个数据:");
for(int i = 0; i < scores.length; i++){
System.out.println("第" + (i + 1) + "个数据是:" + scores[i]);
}
}
}
- 静态初始化
int[] a = {1, 2, 3}
int a[] = new int[3];
int[] a;
a = new int[4]; - 数组的细节
public class ArrayDetail{
public static void main(String[] args) {
// 1.数组是多种数据类型的组合,可以实现对数据的统一管理
//
//
// int[] arr1 = {1, 2, 3, 60, "hello"}; // 报错,类型不一致且没有办法自动转换
double[] arr2 = {1.1, 2.2, 3.3, 60.0, 22}; // 可以,因为可以自动转换
// 数组中的元素可以是任何数据类型,包括基本类型和引用类型,但是不能混用。
String[] arr3 = {"北京", "Jack", "mailln"};
// 数组创建后,如果没有赋值,有默认值
// int, short, byte, long, 0
// float, double 0.0
// char \u0000.
// boolean false
// String null
short[] arr4 = new short[3];
for(int i = 0; i < arr4.length; i++){
System.out.println(arr4[i]);
}
// 使用数组的步骤 1. 声明数组并开辟空间 2 给数组各个元素赋值 3 使用数组
// 数组的下标是从 0 开始的
// 数组下标必须在指定范围内使用,否则报:下标越界异常,比如
// 数组的最大值是长度减一
int[] arr = new int[5];
System.out.println(arr[5]);
// 数组属引用类型,数组型数据是对象(object)
}
}
- 数组练习1
创建一个 char 类型的 26 个元素的数组,分别 放置'A'-'Z'。
使用 for 循环访问所有元素并打印出来 提示:char 类型 数据运算 'A'+2 -> 'C'
//创建一个 char 类型的 26 个元素的数组,分别 放置'A'-'Z'。
//使用 for 循环访问所有元素并打印出来 提示:char 类型 数据运算 'A'+2 -> 'C' ArrayExercise01.java
public class ArrayEx01{
public static void main(String[] args) {
/*
思路分析:1.定义一个数组,char[] chars = new char[26];
2. 因为 'A' + 1 = 'B'; 使用for赋值
3. 使用for循环访问所有元素
*/
char[] characters = new char[25];
char j='A';
for(int i = 0; i< characters.length; i++){
characters[i] = (char)(j + i); // 'A' + i 是int,需要强制转换
}
for (int i=0; i < characters.length; i++){
System.out.print(characters[i] + " ");
}
}
}
- 数组练习2
请求出一个数组 int[]的最大值 {4,-1,9, 10,23},并得到对应的下标
//请求出一个数组 int[]的最大值 {4,-1,9, 10,23},并得到对应的下标
//
public class ArrayEx02{
public static void main(String[] args) {
int[] nums = {4, -1, 9, 10, 23};
/*
思路分析:定义一个最大值为数组第一个值, int maxNum = nums[0];
1. 循环遍历所有的数,如果比第一个数大,则赋值给最大值
*/
int maxNum = nums[0];
int maxIndex = 0;
for (int i = 0; i < nums.length; i++){
if (nums[i] > maxNum){
maxNum = nums[i];
maxIndex = i;
}
}
System.out.println("数组的最大值:" + maxNum);
}
}
- 练习3
请求出一个数组的和和平均值。
// 请求出一个数组的和和平均值。
//
public class ArrayEx02{
public static void main(String[] args) {
int[] nums = {4, -1, 9, 10, 23};
/*
思路分析:
1. 循环遍历所有的数,加起来
*/
int sum = 0;
for (int i = 0; i < nums.length; i++){
sum += nums[i];
}
System.out.println("数组的和:" + sum + " 数组的平均值:" + sum*1.0/nums.length);
}
}
数组的赋值机制
- 基本数据类型赋值,这个值就是具体的数据,而且相互不影响。 int n1 = 2; int n2 = n1;
- 数组在默认情况下是引用传递,赋的值是地址
- 可以看到两者的区别
public class ArrayAssign{
public static void main(String[] args) {
//基本数据类型赋值, 赋值方式为值拷贝
//n2的变化不会影响到n1
int n1 = 10;
int n2 = n1;
n2 = 80;
System.out.println("n1=" + n1);
System.out.println("n2=" + n2);
// 数组在默认情况下是引用分配,赋值的是地址,赋值方式是引用传达
// 是一个地址,arr2的变化会影响到 arr1
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1;
arr2[0] = 10;
System.out.println("=======arr1的元素=======");
for(int i = 0; i<arr1.length; i++){
System.out.print(arr1[i] + " ");
}
System.out.println("\n=======arr2的元素=======");
for(int i = 0; i < arr2.length; i++){
System.out.print(arr2[i] + " ");
}
}
}
- 内存的空间图
- 得到一个新的数组,不影响原来的数组,数组拷贝,要求数据空间是独立的
public class ArrayCopy{
public static void main(String[] args) {
// 将 int[] arr1 = {10,20,30}; 拷贝到 arr2 数组, 要求数据空间是独立的.
int[] arr1 = {10, 20, 30};
// 先创建一个新的数组,arr2,开辟新的数据空间
int[] arr2 = new int[arr1.length];
for(int i = 0; i < arr1.length; i++){
arr2[i] = arr1[i];
}
arr2[0] = 30;
System.out.println("=====打印arr1d值=======");
for(int i = 0; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
}
}
数组翻转
要求:把数组的元素内容反转。
// 要求:把数组的元素内容反转
//
public class ArrayReverse{
public static void main(String[] args) {
// 通过找规律反转
// 通过逆序赋值的方式
int[] arr1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int start = 0;
int end = arr1.length - 1;
int temp = 0;
while (start < end){
temp = arr1[start];
arr1[start] = arr1[end];
arr1[end] = temp;
start++;
end--;
}
// 类始于第一种方式,但是用for循环
int len = arr1.length;
int temp = 0;
for (int i = 0; i < len/2; i++){
temp = arr1[i];
arr1[i] = arr1[len-1-i];
arr1[len-i-1] = temp;
}
for(int i=0; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
// 通过创建一个新的交换空间
int[] arr2 = new int[arr1.length];
for(int i = 0; i < arr1.length; i++){
arr2[i] = arr1[arr1.length-1-i];
}
for(int i = 0; i < arr2.length; i++){
System.out.print(arr2[i] + " ");
}
}
}
数组的扩容
- 原始数组使用静态分配 int[] arr = {1,2,3}
- 增加的元素 4,直接放在数组的最后 arr = {1,2,3,4}
- 用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
// 实现动态的给数组添加元素效果,实现对数组扩容
import java.util.Scanner;
public class ArrayAdd{
public static void main(String[] args) {
/*
思路: while True, 不添加跳出 break
2. 每次创建一个新的数组,在之前的数据数量增加一个数据
3. 添加成功,提示是否继续
1) 原始数组使用静态分配 int[] arr = {1,2,3}
2) 增加的元素 4,直接放在数组的最后 arr = {1,2,3,4}
3) 用户可以通过如下方法来决定是否继续添加,添加成功,是否继续?y/n
*/
int[] arr = {1, 2, 3};
Scanner myScanner = new Scanner(System.in);
int[] arrNew = arr;
while(true){
System.out.println("是否需要添加数组元素(y/n):");
char chara = myScanner.next().charAt(0);
if (chara == 'y'){
arrNew = new int[arr.length + 1];
System.out.println("输入添加的数字:");
int num = myScanner.nextInt();
for (int i = 0; i < arr.length; i++){
arrNew[i] = arr[i];
}
arrNew[arrNew.length-1] = num;
arr = arrNew;
}
else{
System.out.println("不需要添加了,结束");
break;
}
}
for (int i = 0; i < arrNew.length; i++){
System.out.print(arrNew[i] + " ");
}
}
}
- 数据缩减
有一个数组 {1, 2, 3, 4, 5}, 可以将该数组进行缩减,提示用户是否继续缩减,每次缩减最后那个元素。
当只剩 下最后一个元素,提示,不能再缩减
// 有一个数组 {1, 2, 3, 4, 5}, 可以将该数组进行缩减,提示用户是否继续缩减,
// 每次缩减最后那个元素。当只剩 下最后一个元素,提示,不能再缩减
import java.util.Scanner;
public class ArrayReduce{
public static void main(String[] args) {
/*
思路:
1.缩减需要定义一个新数组
2.新数组的长度比原数组减一
3.原数组指向新数组
*/
int[] arr = {1, 2, 3, 4, 5};
int[] arrNew = arr;
Scanner myScanner = new Scanner(System.in);
while(true){
System.out.println("是否要缩减数组(y/n):");
char chara = myScanner.next().charAt(0);
if (chara == 'y'){
if (arr.length == 1){
System.out.println("只剩下最后一个元素,不能再缩减");
break;
}
arrNew = new int[arr.length-1];
for(int i =0; i < arrNew.length; i++){
arrNew[i] = arr[i];
}
arr = arrNew;
}
else{
break;
}
}
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
排序
排序是将多个数据,依指定的顺序进行排列的过程。 排序的分类:
- 内部排序: 指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择 式排序法和插入式排序法)
- 数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)。
冒泡排序
冒泡排序(Bubble Sorting)的基本思想是:通过对待排序序列从后向前(从下标较大的元素开始),依次比较相邻元素 的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。
public class BubbleSort{
public static void main(String[] args) {
/*
思路:每一次循环都要确定最大的数,放到最后
1. 第一轮循环确定最后的数是最大的,每相邻两个数进行比较,如果前面的数大于后面的数,进行交换
2. 循环的次数是 arr.length - 1;
*/
int[] arr = {24, 69, 80, 57, 13};
int temp = 0;
for(int i=0; i < arr.length-1; i++){
for(int j = 0; j < arr.length-1 - i; j++){
if(arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
}
}
查找
- 顺序查找
import java.util.Scanner;
public class SeqSearch{
public static void main(String[] args) {
// 有一个数列:白眉鹰王、金毛狮王、紫衫龙王、青翼蝠王猜数游戏:
// 从键盘中任意输入一个名称,判断数列中是否包含此名称【顺序查找】
/*
思路:
遍历数组,
逐个比较,如果相等,break退出
*/
String[] names = {"白眉鹰王", "金毛狮王", "紫衫龙王", "青翼蝠王"};
Scanner myScanner = new Scanner(System.in);
int index = -1;
label1:
do{
System.out.println("请输入名字:");
String name = myScanner.next();
label2:
for(int i =0; i < names.length; i++){
if(name.equals(names[i])){
System.out.println("找到了" + name);
System.out.println("下标=" + i);
index = i;
break label1;
}
}
if (index == -1){
System.out.println("sorry, 没有找到" + name);
}
}while(true);
}
}
- 二分查找
多维数组
- 多维数组我们介绍二维数组
- 比如棋盘就是一个二维数组
- 快速入门
请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
public class TwoDimensionalArray01{
public static void main(String[] args) {
/*
请用二维数组输出如下图形
0 0 0 0 0 0
0 0 1 0 0 0
0 2 0 3 0 0
0 0 0 0 0 0
*/
// 什么是二维数组
// 从定义形式看 int[][]
// 可以理解为原来的每个数组是 一维数组,就构成二维数组
int[][] arr = {{0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 2, 0, 3, 0, 0},
{0, 0, 0, 0, 0, 0},
};
// 输出二维数组
for(int i = 0; i < arr.length; i++){
// 遍历二维数组的每个元素(数组)
for(int j = 0; j < arr[i].length; j++){
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
}
}
- 数组的练习
已知有个升序的数组,要求插入一个元素,该数组依然是升序的
import java.util.Scanner;
public class Homework04{
public static void main(String[] args) {
/*
有个升序的数组,{10, 12, 23, 45, 90}, 插入一个数字后,仍然保持升序
思路: 定义插入的int insertNum , 找到插入的位置
将元素组的数据都复制到新数组,
*/
Scanner myScanner = new Scanner(System.in);
int arr[] = {10, 12, 23, 45, 90};
int tempPath = -1;
int[] newArr;
System.out.println("请输入插入数字:");
int insertNum = myScanner.nextInt();
// 要赋值到新数组, 同时将小于该数的值赋值到新数组中
// 找到要赋值的位置
newArr = new int[arr.length+1];
// 笨的办法就是插入到最后,然后在冒泡排序
// 聪明的办法是找到比他的大的值,然后移动
/*
要一个一个的移动到新数组中的循环是
先找到要插入的值的位置
*/
for(int i = 0; i < arr.length; i++){
if(insertNum < arr[i]){
tempPath = i;
break;
}
}
if (tempPath == -1){
tempPath = arr.length;
}
for(int i=0, j=0; i < newArr.length; i++){
if(tempPath == i){
newArr[i] = insertNum;
}
else{
newArr[i] = arr[j];
j++;
}
}
System.out.println("====插入后的新数组的值======");
for(int i = 0; i < newArr.length; i++){
System.out.print(newArr[i] + " ");
}
}
}
- 数组练习
求数组的最大值和下标,平均数和求和
public class Homework05{
public static void main(String[] args) {
/*
随机生成10个整数(1-100)保存到数组
并倒序打印以及求出平均值,求最大值和最小值的下标
并查找里面是否有8
*/
int[] arr = new int[10];
for(int i=0; i < arr.length; i++){
arr[i] = (int)(Math.random() * 100) + 1;
}
//
System.out.println("====arr的元素情况====");
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println("\n=====arr逆序打印=======");
for(int i = 0; i < arr.length; i++){
System.out.print(arr[arr.length-1-i] + " ");
}
// 求最大值的下标和求和
int sum = 0;
int maxIndex = 0;
int maxNum = arr[0];
for(int i = 0; i < arr.length; i++){
sum += arr[i];
if(arr[i] > maxNum){
maxNum = arr[i];
maxIndex = i;
}
}
System.out.println("求和:" + sum + " 平均值:" + sum/(arr.length * 1.0));
System.out.println("最大值:" + maxNum + " 最大值下标:" + maxIndex);
int findNum = 8;
int findIndex = -1;
for(int i = 0; i < arr.length; i++){
if(arr[i] == findNum){
System.out.println("找到了" + findNum + " 下标:" + i);
findIndex = i;
break;
}
}
if(findIndex == -1){
System.out.println("没有找到这个数");
}
}
}
- 数组练习
写出冒泡排序法,从小到大
public class Homework06{
public static void main(String[] args) {
int arr[] = {20, 12, 8, 79, 45, 90};
int temp = 0;
for(int i = 0; i < arr.length; i++){
for (int j = 0; j < arr.length-1-i; j++){
if(arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (int i = 0; i < arr.length ; i++ ) {
System.out.print(arr[i] + " ");
}
}
}