继续记录Java的基础知识,方便自己查看,各位要是有需要也可以copy一下。
本期笔记的内容有:一维数组、二维数组
一维数组的内存的一些解析:
以五行代码为例:
int[] arr = new int[]{1,2,3};
String[] arr1 = new String[4];
arr1[1] = "刘德华";
arr1[2] = "张学友";
arr1 = new String[3];
创建了一个名为arr的int类型的一维数组和一个名为arr1的String类型的一维数组,并给arr数组中的三项分别赋值1、2、3,给arr1数组的第二项赋值 “刘德华” 、第三项赋值 “张学友”。变量名arr和arr1都存放在栈中,而这些通过new创建的数据则存放在堆中,堆根据代码的命令(例如数组arr)创建一个相对应的数组(数组中每一项的值都为初始值),这个被创建出来的数组会有一个首地址值(通常用一个十六进制的数表示,图中假设首地址值为:0x34ab),这个首地址值会赋值给存放在栈中的变量名arr,由此变量名arr便可通过赋值的首地址值,准确找到存放在堆中的所对应的数组,并给这个数组赋值1、2、3。
如下图:
数组arr1同理,如下图:
以上四句代码执行完后,看到第五句代码“arr1 = new String[3]”,给变量名arr1再赋值一个新的长度为三的String类型的数组,该数组的首地址值为:0x5566,此时,变量名arr1所指向的数组发生了变化,变量名arr1中的值则从原先的0x12ab变成了0x5566,由于变量名arr1赋值的地址值发生了变化,变量名arr1不再指向原先的数组,指向了新创建的首地址值为0x5566的数组。
二维数组的内存的一些解析:
规定:二维数组分为外层数组元素、内层数组元素。
int[][] arr = new int[4][3];
外层元素:arr[0]、arr[1]、arr[2]…
内层元素:arr[0][0]、arr[0][1]、arr[0][2]…
以四行代码为例:
int[][] arr1 = new int[4][];
arr1 = new int[]{1,2,3};
arr1 = new int[4];
arr1[2][1] = 30;
第一行代码“int[][] arr1 = new int[4][];”,堆根据代码的命令创建了一个名为arr1的int类型的一维数组,给arr数组中的外层元素赋值一个4。和一维数组一样,变量名arr1存放在栈中,而这些通过new创建的数据则存放在堆中,堆根据代码的指示创建一个拥有四个存储空间的一维数组(由于二维数组arr1数组的内层元素未声明空间,所以每一项的值都看作为一维数组int[],初始值为null),创建出来的这个一维数组会有一个首地址值(通常用一个十六进制的数表示,图中假设首地址值为:0x1234),这个首地址值会赋值给存放在栈中的变量名arr1,由此变量名arr1便可通过赋值的首地址值,准确找到存放在堆中的所对应的数组。
如下图:
第二行代码“arr1 = new int[]{1,2,3};”,堆根据代码的命令创建一个拥有三个存储空间的int类型的一维数组(每一项的值都看作为一维数组int[]的初始值0),创建出来的这个一维数组会有一个首地址值(通常用一个十六进制的数表示,图中假设首地址值为:0x7788),这个首地址值会赋值给第一行代码创建出来的一维数组的第二项中,由此第一行代码创建出来的一位数组的第二项的值便从原来的null变成了第二行代码所创建出来的一维数组的首地址值,并根据代码的指示,给这个一维数组的三个存储空间分别赋值1、2、3。
第三行代码“arr1 = new int[4];”,堆根据代码的命令创建一个拥有四个存储空间的int类型的一维数组(由于第一行代码处,该二维数组是一个int类型的二维数组,所以每一项的值都看作为一维数组int[]的初始值0),创建出来的这个一维数组会有一个首地址值(通常用一个十六进制的数表示,图中假设首地址值为:0x6677),这个首地址值会赋值给第一行代码创建出来的一维数组的第三项中,由此第一行代码创建出来的一维数组的第三项的值便从原来的null变成了第三行代码所创建出来的一维数组的首地址值。
第四行代码“arr1[2][1] = 30;”,堆根据代码的命令,找到二维数组arr1的第三个外层元素所指向的数组中的第二项,并将该项的值由原来的0更改为30。
package lian_xi;
import java.util.Scanner; //导入输入函数
/*
* 一、数组的概述
* 1)数组的理解:数组(Array),是多个相同类型数据按照一定顺序排列的集合,并使用一个名字
* 命名,并通过编号的方式对这些数据进行统一管理。
*
* 2)数组相关的概念:
* ① 数组名
* ② 元素
* ③ 角标、下标(索引)
* ④ 数组的长度:元素的个数
*
* 3)数组的特点:
* ① 数组是有序排列的(排列顺序自己定义)
* ② 数组本身是引用数据类型的变量,而数组中的元素可以是任何数据类型,包括基本数据类型和引
* 用数据类型。
* ③ 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
* ④ 数组的长度一旦确定,就不能修改。
* ⑤ 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
*
* 4)数组的分类:
* ① 按照维度:一维数组、二维数组、三维数组、...
* ② 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)
*
* 5)一维数组的使用:
* ① 一维数组的声明和初始化方式: type VAR[]; 或 type[] VAR;
* 总结:数组一旦初始化完成,其长度就确定了,不可改变。
*
* ② 如何调用数组指定位置的元素:数组名[数组元素下标]
* 总结:a.数组元素下标可以是整型常量或整型表达式。如 a[3],b[i],c[6*i];
* b.数组元素下标从 0 开始:长度为n的数组合法下标取值范围:0——>n-1 如int a[]=new int [3];
* 可引用的数组元素为 a[0]、a[1]、a[2];
*
* ③ 如何获取数组的长度: 属性 length
* 总结:a.length,指明数组a的长度(元素个数)
*
* ④ 如何遍历数组:直接输出或者使用for循环之类的循环结构
*
* ⑤ 数组元素的默认初始化值
* 总结:a.数组元素是整数型:0
* b.数组元素是浮点型:0.0
* c.数组元素是char型:ASCII码中的0 或 '\u0000' , 而非'0'
* d.数组元素是boolean型:false
* e.数组元素是引用数据类型:null(空值)
*
* ⑥ 数组的内存解析:
* 总结:a.栈(stack): 局部变量
* b.堆(heap): new出来的结构、对象、数组
* c.方法区: 常量池、静态池
*
*/
public class lianxi04 {
public static void main(String[] args) {
// ① 一维数组的声明和初始化方式: type VAR[]; 或 type[] VAR;
//例如:
int[] ids; //声明
//1.1静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
int[] namess = {1,2,3,4,5,6};
/* 错误的写法:
* ① int[] arr1 = new int[]; 未声明长度
* ② int[5] arr2 = new int[5]; 前方中括号内不能有值
* ③ int[] arr3 = new int[5]{1,2,3}; 动态初始化和静态初始化不能合并使用
*
* 总结:数组一旦初始化完成,其长度就确定了,不可改变。
*/
// ② 如何调用数组指定位置的元素:数组名[数组元素下标]
//数组元素下标从 0 开始:长度为n的数组合法下标取值范围:0——>n-1
//例如:
names[0] = "一";
names[1] = "二";
names[2] = "三";
names[3] = "四";
names[4] = "五";
// ③ 如何获取数组的长度:每个数组都有一个属性 length 指明它的长度
//例如: a.length 指明数组 a 的长度 元素个数
System.out.println("数组ids的长度为:" + ids.length); //数组ids的长度为4
System.out.println("数组names的长度为:" + names.length); //数组names的长度为5
System.out.println("数组namess的长度为:" + namess.length); //数组ids的长度为6
// ④ 如何遍历数组: 直接输出或者使用for循环之类的循环结构
//方法一:
System.out.print(names[0]);
System.out.print(names[1]);
System.out.print(names[2]);
System.out.print(names[3]);
System.out.print(names[4]+'\n');
//方法二:
for( int i = 0 ; i < names.length ; i++ ) {
System.out.print(names[i]);
}System.out.println(); //换行
// ⑤ 数组元素的默认初始化值:
int[] arr1 = new int[4];
for( int i = 0 ; i < arr1.length ; i++ ) {
System.out.print(arr1[i]); //输出0
}System.out.println(); //换行
short[] arr2 = new short[4];
for( int i = 0 ; i < arr2.length ; i++ ) {
System.out.print(arr2[i]); //输出0
}System.out.println(); //换行
char[] arr3 = new char[4];
for( int i = 0 ; i < arr3.length ; i++ ) {
System.out.print(arr3[i]); //输出ASCII码中的0 或 '\u0000' , 而非'0'
}System.out.println(); //换行
boolean[] arr4 = new boolean[4];
for( int i = 0 ; i < arr4.length ; i++ ) {
System.out.print(arr4[i]); //输出false
System.out.print('\t');
}System.out.println(); //换行
String[] arr5 = new String[4];
for( int i = 0 ; i < arr5.length ; i++ ) {
System.out.print(arr5[i]); //输出null(空值)
System.out.print('\t');
}System.out.println(); //换行
/* 练习;
* 从键盘读入学生成绩,找出最高分,
* 并输出学生成绩等级。
* 成绩 >= 90 并且 成绩<= 100 等级为 ’A’
* 成绩 >= 80 并且 成绩< 90 等级为 ’B’
* 成绩 >= 70 并且 成绩< 80 等级为 ’C’
* 成绩 >= 60 并且 成绩< 70 等级为 ’D’
* 其余 等级 为 ‘E’
*
* 提示:先读入学生人数,根据人数创建int数组,存放学生成绩、
*/
System.out.println("一维数组练习:");
// 1)使用Scanner,读取学生个数。
Scanner scanner = new Scanner(System.in); //Scanner的实例化
System.out.print("请输入学生人数:");
int number = scanner.nextInt();
// 2)创建数组,存储学生成绩,动态初始化。
int[] scores = new int[number];
// 3) 给数组中的元素赋值。
int maxScore = 0; //用于记录最高分的分数
int ranking = 0; //用于记录最高分在第几位
System.out.println("请输入" + number + "个学生成绩(成绩不大于100,不小于0):");
for( int i = 0 ; i < scores.length ; i++ ) {
scores[i] = scanner.nextInt();
// 4) 在for循环中嵌套一个if判定来获取数组中的元素的最大值(即最高分)
if ( maxScore < scores[i] ) {
maxScore = scores[i];
ranking = i+1;
}
}
//输出最高分
System.out.println("其中成绩最高的是第"+ ranking +"位学生,其成绩为:"+ maxScore);
// 5) 判断每个学生的等级,并输出成绩和等级
for( int i = 0 ; i < scores.length ; i++ ) {
if( scores[i] >= 90 && scores[i] <= 100 ) {
System.out.println("第"+ (i+1) +"位学生的等级为:A 成绩:"+ scores[i]);
}else if( scores[i] >= 80 && scores[i] < 90 ) {
System.out.println("第"+ (i+1) +"位学生的等级为:B 成绩:"+ scores[i]);
}else if( scores[i] >= 70 && scores[i] < 80 ) {
System.out.println("第"+ (i+1) +"位学生的等级为:C 成绩:"+ scores[i]);
}else if( scores[i] >= 60 && scores[i] < 70 ) {
System.out.println("第"+ (i+1) +"位学生的等级为:D 成绩:"+ scores[i]);
}else if( scores[i] >= 0 && scores[i] < 60 ) {
System.out.println("第"+ (i+1) +"位学生的等级为:E 成绩:"+ scores[i]);
}
}
/*
* 二维数组的使用:
* 规定:二维数组分为外层数组元素、内层数组元素。
* int[][] arr = new int[4][3];
* 外层元素:arr[0]、arr[1]、arr[2]....
* 内层元素:arr[0][0]、arr[0][1]、arr[0][2]....
*
* 1)理解:对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维
* 数组 array2 的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。
*
* 5)二维数组的使用:
* ① 二维数组的声明和初始化方式:
* 格式一(静态初始化): int[][] arr = new int[][]{{1,2,3},{4,5},{6,7,8}};
* 格式二(动态初始化):int[][] arr = new int[n][m];
* 格式三(动态初始化):int[][] arr = new int[n][];
* 格式四(动态初始化): int arr[][] = new int [n][m];
* 格式五(动态初始化): int[] arr[] = new int [n][m];
* 格式六(动态初始化): int[][] arr = {{1,2,3},{4,5},{6,7,8}};
* 总结:数组一旦初始化完成,其长度就确定了,不可改变。
*
* ② 如何调用数组指定位置的元素:数组名[数组元素下标][数组元素下标]
* 总结:a.数组元素下标可以是整型常量或整型表达式。如 a[3][2],b[i][n],c[6*i][n*i];
* b.数组元素下标从 0 开始:长度为n的数组合法下标取值范围:0——>n-1 如int a[]=new int [3][2];
* 可引用的数组元素为 a[0][0]、 a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1];
*
* ③ 如何获取数组的长度: 属性 length
* 总结:arr.length,指明数组arr的外层的长度(元素个数)
* arr[n].length,指明数组arr第n层的长度(元素个数)
*
* ④ 如何遍历数组:直接输出或者使用for循环之类的循环结构
*
* ⑤ 数组元素的默认初始化值
* 总结:
* 针对于初始化方式一: 如:int[][] arr = new int[n][m];
* 对于变量名本身来说:
* 数组的初始值为: 首地址值
* 对于外层元素来说:
* 数组的初始值为: 首地址值
* 对于内层元素来说:
* a.数组元素是整数型:0
* b.数组元素是浮点型:0.0
* c.数组元素是char型:ASCII码中的0 或 '\u0000' , 而非'0'
* d.数组元素是boolean型:false
* e.数组元素是引用数据类型:null(空值 )
*
* 针对于初始化方式二: 如:int[][] arr = new int[n][];
* 对于变量名本身来说:
* 数组的初始值为: 首地址值
* 对于外层元素来说:
* 数组的初始值为: null
* 对于内层元素来说:
* 无初始化,报错,错误原因”空指针异常“
*
* ⑥ 数组的内存解析:
* 总结:a.栈(stack): 局部变量
* b.堆(heap): new出来的结构、对象、数组
* c.方法区: 常量池、静态池
*/
// ① 二维数组的声明和初始化方式:
//格式一(静态初始化): int[][] arr = new int[][]{{1,2,3},{4,5},{6,7,8}};
int[][] arr6 = new int[][]{{1,2,3},{4,5},{6,7,8}};
// 格式二(动态初始化): int[][] arr = new int [n][m];
String[][] arr7 = new String[3][2];
// 格式三(动态初始化): int[][] arr = new int [n][];
String[][] arr8 = new String[3][];
// 格式四(动态初始化): int arr[][] = new int [n][m];
String arr9[][] = new String[3][2];
// 格式五(动态初始化): int[] arr[] = new int [n][m];
String[] arr10[] = new String[3][2];
// 格式六(动态初始化): int[][] arr = {{1,2,3},{4,5},{6,7,8}};
int[][] arr11 = {{1,2,3},{4,5},{6,7,8}};
/* 错误的写法:
* ① String[][] arr = new String[][m];
* ② String[n][m] arr = new String[][];
* ③ String[n][m] arr = new String[n][m];
*
* 总结:数组一旦初始化完成,其长度就确定了,不可改变。
*/
// ② 如何调用数组指定位置的元素:数组名[数组元素下标][数组元素下标]
System.out.println(arr6[0][1]); //输出2
System.out.println(arr7[0][1]); //输出null(空值)
System.out.println(arr9[0][1]); //输出null(空值)
System.out.println(arr10[0][1]); //输出null(空值)
System.out.println(arr11[0][1]); //输出2
//不能直接输出数组arr8,因为数组arr8的第二个维度还未赋值,若直接输出会出现“空指针异常”
arr8[1] = new String[4];
System.out.println(arr8[1][0]); //输出null(空值)
// ③ 如何获取数组的长度: 属性 length
System.out.println("数组arr6的外层有"+ arr6.length +"个元素"); //输出3
System.out.println("数组arr6第1层中有"+ arr6[0].length +"个元素"); //输出3
// ④ 如何遍历数组:直接输出或者使用for循环之类的循环结构
System.out.println("数组arr6里的各项如下:"); //输出3
for ( int i = 0 ; i < arr6.length ; i++ ) {
for (int j = 0 ; j < arr6[i].length ; j++) {
System.out.print(arr6[i][j] + "\t"); //输出3
}
System.out.println(); //换行
}
// ⑤ 数组元素的默认初始化值
int[][] arr12 = new int[4][3];
System.out.println(arr12); //输出 [[I@74a14482 (首地址值)
System.out.println(arr12[0]); //输出 [I@1540e19d (首地址值)
System.out.println(arr12[0][0]); //输出 0
float[][] arr13 = new float[4][3];
System.out.println(arr13); //输出 [[F@677327b6 (首地址值)
System.out.println(arr13[0]); //输出 [F@14ae5a5 (首地址值)
System.out.println(arr13[0][0]); //输出 0.0
char[][] arr14 = new char[4][3];
System.out.println(arr14); //输出 [[C@7f31245a (首地址值)
System.out.println(arr14[0]); //输出 ASCII码中的0 或 '\u0000' , 而非'0'
System.out.println(arr14[0][0]); //输出 ASCII码中的0 或 '\u0000' , 而非'0'
boolean[][] arr15 = new boolean[4][3];
System.out.println(arr15); //输出 [[Z@6d6f6e28 (首地址值)
System.out.println(arr15[0]); //输出 [Z@135fbaa4 (首地址值)
System.out.println(arr15[0][0]); //输出 false
String[][] arr16 = new String[4][3];
System.out.println(arr16); //输出 [[Ljava.lang.String;@45ee12a7 (首地址值)
System.out.println(arr16[0]); //输出 [Ljava.lang.String;@330bedb4 (首地址值)
System.out.println(arr16[0][0]); //输出 null
//特殊情况:
String[][] arr17 = new String[4][];
System.out.println(arr17); //输出 [[Ljava.lang.String;@2503dbd3 (首地址值)
System.out.println(arr17[0]); //输出 null
//System.out.println(arr16[0][0]); 报错,错误原因”空指针异常“
//二维数组练习1:求和
System.out.println("二维数组练习一:求和");
int[][] arr18 = new int[][]{{3,6,9},{8,16},{1,3,5}};
//sum记录总和
int sum = 0;
//使用嵌套循环实现累加效果
for( int i = 0 ; i < arr18.length ; i++ ) {
for( int j = 0 ; j < arr18[i].length ; j++ ) {
sum += arr18[i][j];
}
}
//输出结果
System.out.println("二维数组arr18的总和为:"+ sum); //输出 51
/*
* 二维数组练习2:
* 声明:int[] x,y[];在给 x,y变量赋值以后,以下选项允许通过编译的是:
* 其中变量x是一维数组,变量y是二维数组。
* a) x[0] = y ; no
* b) y[0] = x ; yes
* c) y[0][0] = x; no
* d) x[0][0] = y; no
* e) y[0][0] = x[0]; yes
* f) x = y; no
*
* 提示:
* 一维数组: int [] x 或者 int x[]
* 二维数组:int [][] y 或者 int [] y[] 或者 int y[][]
*/
/*
* 二维数组练习3:使用二维数组打印一个10 行杨辉三角。
* 提示 :
* 1)第一行有 1 个元素 , 第 n 行有 n 个元素
* 2)每一行的第一个元素和最后一个元素都是 1
* 3)从第三行开始 , 对于非第一个元素和最后一个元素的元素。即:
* yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
*/
System.out.println("二维数组练习3:使用二维数组打印一个10 行杨辉三角。");
//声明一个外层元素为10的二维函数。
int[][] yangHui = new int[10][];
for (int i = 0 ; i < yangHui.length ; i++ ) {
//给数组元素赋值
yangHui[i] = new int[i+1];
//杨辉三角的首元素和末元素都是1
yangHui[i][0] = yangHui[i][i] = 1;
//给每一行的非首末元素赋值
//(yangHui[i].length - 1)减一是为了不让赋值到最后一个元素。
for (int j = 1 ; j < (yangHui[i].length - 1) ; j++) {
yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
}
//打印杨辉三角
for (int j = 0; j < yangHui[i].length; j++) {
System.out.print(yangHui[i][j] + "\t");
}
System.out.println();
}
/*
* 数组中涉及的常见算法:
* 1)数组元素的赋值 杨辉三角、回形数等(见上方例题)
* 2)求数值型 数组中元素 的最大值、最小值、平均数、总和等
* 3)数组的复制 、反转、查找 线性查找、二分法查找
* 4)数组元素 的 排序算法
*/
// 1)数组元素的赋值 杨辉三角、回形数等(见上方例题)
// 例题:创建一个长度为 6 的 int 型数组,要求数组元素的值都在 1 30 之间,
// 且是随机赋值。同时,要求元素的值各不相同。
System.out.println("\n数组练习1:数组元素的赋值。");
int[] arr19 = new int[6];
for (int i = 0 ; i < arr19.length ; i++ ) {
//给arr19赋值,值的范围为1-30之间的随机数。
arr19[i] = (int) (Math.random() * 30) + 1;
//在for循环内嵌套一个if判定,判断新赋的值与数组里面已有的值是否相同,如果相同就重新赋值
for (int j = 0; j < i ; j++) {
if ( arr19[i] == arr19[j] ) {
i--;
break;
}
}
}
//遍历数组
System.out.print("数组arr19内的各项值为:");
for (int i = 0; i < arr19.length; i++) {
System.out.print(arr19[i] +"\t");
}
System.out.println(); //换行
/*
* 回形数格式方阵的实现
* 从键盘输入一个整数(1~20)
* 则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。
* 例如: 输入数字2,则程序输出: 1 2
* 4 3
* 输入数字3,则程序输出: 1 2 3
* 8 9 4
* 7 6 5
* 输入数字4, 则程序输出:
* 1 2 3 4
* 12 13 14 5
* 11 16 15 6
* 10 9 8 7
*/
System.out.println("\n数组练习2:回形数格式方阵的实现。");
System.out.println("请输入回形数格式方阵的行数:");
int n = 0;
n = scanner.nextInt();
int[][] arr = new int[n][n];
int count = 0; // 要显示的数据
int maxX = n - 1; // x轴的最大下标
int maxY = n - 1; // Y轴的最大下标
int minX = 0; // x轴的最小下标
int minY = 0; // Y轴的最小下标
while (minX <= maxX) {
for (int x = minX; x <= maxX; x++) {
arr[minY][x] = ++count;
}
minY++;
for (int y = minY; y <= maxY; y++) {
arr[y][maxX] = ++count;
}
maxX--;
for (int x = maxX; x >= minX; x--) {
arr[maxY][x] = ++count;
}
maxY--;
for (int y = maxY; y >= minY; y--) {
arr[y][minX] = ++count;
}
minX++;
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
String space = (arr[i][j] + "").length() == 1 ? "0" : "";
System.out.print(space + arr[i][j] + " ");
}
System.out.println();
}
/*
* 2)求数值型 数组中元素 的最大值、最小值、平均数、总和等
* 例题:定义一个int型的一维数组,包含 10 个元素,分别赋一些随机整数,
* 然后求出所有元素的最大值, 最小值,和值、平均值,并输出 出来 。
* 要求:所有随机数都是两位数。
* 提示;
* [0,1) * 90 → [0,90) + 10 → [10,100) → [10,99]
* (int)(Math.random() * ( 99 - 10 + 1 ) + 10
*/
System.out.println("数组练习3:赋10 个元素,输出最大值, 最小值,和值、平均值。");
int[] arr20 = new int[10];
//记录大值:
int maxValue = arr20[0];
//记录小值:
int minValue = 100;
//记录平均值:
int avfValue = arr20[0];
//记录和值:
int sum1 = 0;
System.out.print("\n数组arr20中的值为:");
for (int i = 0 ; i < arr20.length ; i++ ) {
//赋值
arr20[i] = (int)(Math.random() * (99-10+1)+10);
//遍历
System.out.print(arr20[i] +"\t");
//求最大值:
if( maxValue < arr20[i] ) {
maxValue = arr20[i];
}
//求最小值:
if( minValue > arr20[i] ) {
minValue = arr20[i];
}
//求和值:
sum1 = sum1 + arr20[i];
}System.out.println();
//求平均值:
avfValue = sum1 / 10;
System.out.println("数组中的最大值为:" + maxValue);
System.out.println("数组中的最小值为:" + minValue);
System.out.println("数组中的和值为:" + sum1);
System.out.println("数组中的平均值为:" + avfValue);
/*
* 3)数组的复制 、反转、查找 线性查找、二分法查找
* (1)创建一个 名为 ArrayTest 的 类,在 main() 方法中声明 array1 和 array2 两 个 变量,
* 他们 是 int 类型的数组。
* (2)使用大括号 {}{},把 array1 初始化为 8 个素数: 2,3,5,7,11,13,17,19 。
* (3)显示 array1 的内容。
* (4)赋值 array2 变量等于 array1 ,修改 array2 中的偶索引元素,使其等于索引值
* (如 array[0]=0,array[2]=2) 。打印出 array1 。
*
*/
System.out.println("\n数组练习4:复制简单数组");
//创建数组array1和array2
int[] array1 = new int[]{2,3,5,7,11,13,17,19};
int[] array2 = new int[array1.length];
//将数组array1的值赋值给array2
System.out.print("数组array1中的值为:");
for ( int i = 0 ; i < array1.length ; i++) {
array2[i] = array1[i];
//遍历数组array1
System.out.print(array1[i] +"\t");
}
for ( int j = 0; j < array2.length ; j++) {
if ( j%2 == 0) {
array2[j] = j;
}
}
//3)数组的复制 、反转、查找 线性查找、二分法查找
System.out.println("\n\n数组练习5:反转简单数组");
for (int i = 0; i < (array1.length/2); i++) {
int x = array1[i];
array1[i] = array1[array1.length-i-1];
array1[array1.length-i-1] = x;
}
System.out.print("数组array1反转后的值为:");
for (int i = 0; i < array2.length; i++) {
//遍历数组array1
System.out.print(array1[i] +"\t");
}
//3)数组的复制 、反转、查找 线性查找、二分法查找
//查找(又称搜索)
//线性查找:
System.out.println("\n\n数组练习6:线性查找,查找数组arr21中是否有 “C“ ");
String[] arr21 = new String[]{"A","B","C","D"};
String dest = "C";
boolean isFlag = true;
//遍历数组arr21
System.out.print("数组arr21的值为:");
for (int i = 0; i < arr21.length; i++) {
System.out.print(arr21[i] +"\t");
}
for ( int i = 0 ; i < array1.length ; i++ ) {
//搜索数组arr21中是否有“C”。
if ( dest.equals(arr21[i]) ) {
System.out.println("\n找到了指定元素,位置在第"+ (i+1) +"项\n");
isFlag = false;
break;
}
}
if (isFlag) {
System.out.println("很遗憾,在数组arr21中没有找到 “C” \n");
}
//3)数组的复制 、反转、查找 线性查找、二分法查找
//二分法查找:(效率比线性查找快)
//前提:所要查找的数组必须有序。
System.out.println("\n\n数组练习7:二分法查找,查找数组arr22中是否有 “-34“ ");
int[] arr22 = new int[] {-98,-34,-2,10,53,95,103,666,698,723};
int dest1 = -34;
int head = 0; //初始的首索引
int end = arr22.length - 1; //初始的末索引
boolean isFlag1 = true;
//遍历数组arr22
System.out.print("数组arr22的值为:");
for (int i = 0; i < arr22.length; i++) {
System.out.print(arr22[i] +"\t");
}
while ( head <= end) {
//取数组arr22中间项的位置
int middle = (head + end)/2;
//判断要寻找的值在中间项的什么位置
if ( dest1 == arr22[middle] ) {
System.out.println("\n找到了指定元素,位置在第"+ (middle+1) +"项\n");
isFlag1 = false;
break;
}else if ( arr22[middle] > dest1 ) {
end = middle - 1;
}else { //这里相对于arr22[middle] < dest1
head = middle + 1;
}
}
if (isFlag1) {
System.out.println("很遗憾,在数组arr22中没有找到 “-34” \n");
}
/*
* 4)数组元素 的 排序算法
* 排序:假设含有 n 个记录的序列为 {R1,R2,...Rn)其相应的关键字序列为
* {K1,K2,...Kn)。将这些记录重新排序为 {Ri1,Ri2,... Rin)使得相应的关键
* 字值满足条 Ki1<=Ki2<=...<=Kin, 这样的一种操作称为排序。
* 通常来说,排序的目的是快速查找。
*
* 衡量排序算法的优劣:
* 1)时间复杂度 :分析关键字的比较次数和记录的移动次数
* 2)空间复杂度: 分析排序算法中需要多少辅助内存
* 3)稳定性: 若两个记录 A 和 B 的关键字值相等,但排序后 A 、 B 的先后次序保
* 持不变,则称这种排序算法是稳定的。
*
* 排序算法分类:内部排序 和 外部排序 。
* 1)内部排序 :整个排序过程不需要借助于外部存储器(如磁盘等),所有排
* 序操作都在内存中完成。
* 2)外部排序 :参与排序的数据非常多,数据量非常大,计算机无法把整个排
* 序过程放在内存中完成,必须借助于外部存储器(如磁盘)。外部排序最
* 常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
*
* 十大内部排序算法
* 1)选择排序:直接选择排序、 堆排序
* 2)交换排序:冒泡排序 、 快速排序
* 3)插入排序:直接插入排序、 折半插入排序、 Shell 排序
* 4)归并排序
* 5)桶式排序
* 6)基数排序
*
* 各种内部排序方法性能比较:
* 1)从平均时间而言 快速排序最佳。 但在最坏情况下时间性能不如堆排序和归并排序。
* 2)从算法简单性看 :由于直接选择排序、直接插入排序和冒泡排序的算法比较
* 简单,将其认为是 简单 算法。 对于 Shell 排序、堆排序、快速排序和归并排序
* 算法,其算法比较复杂,认为是复杂排序。
* 3)从稳定性看 :直接插入排序、冒泡排序和归并排序时稳定的;而直接选择排
* 序、快速排序、 Shell 排序和堆排序是不稳定排序
* 4)从待排序的记录数 n 的大小看 n 较小时,宜采用简单排序;而 n 较大时宜采
* 用改进排序。
*
* 排序算法的选择:(见文章末图片)
* 1)若 n 较小 (如 n≤50)可采用 直接插入 或 直接选择排序 。
* 当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直
* 接插入,应选直接选择排序为宜 。
* 2)若文件初始状态基本有序(指正序),则应选用直接插入、冒泡或随机的快速排
* 序为宜。
* 3)若n较大,则应采用时间复杂度为 O(nlgn)的排序方法:快速排序、堆排序或
* 归并排序 。
*/
System.out.println("\n\n数组练习8:冒泡排序 ");
int[] arr23 = new int[] {-98,-3,66,89,55,32,0,-65,88,100};
//遍历数组arr23
System.out.print("数组arr23的值为:");
for (int i = 0; i < arr23.length; i++) {
System.out.print(arr23[i] +"\t");
}System.out.println();
for( int i = 0 ; i < arr23.length ; i++ ) {
for(int j = 0; j < (arr23.length-i-1); j++) {
if (arr23[j] > arr23[j+1]) {
int temp = arr23[j];
arr23[j] = arr23[j+1];
arr23[j+1] = temp;
}
}
}
//遍历数组arr23
System.out.print("数组arr23的值为:");
for (int i = 0; i < arr23.length; i++) {
System.out.print(arr23[i] +"\t");
}System.out.println();
/*
* 快速排序
* 介绍:
* 快速排序通常明显比同为O(nlogn) 的其他算法更快,因此常被采用,而且快
* 排采用了分治法的思想,所以在很多笔试面试中能经常看到快排的影子。可
* 见掌握快排的重要性 。
*
* 快速排序(Quick Sort )由图灵奖获得者 Tony Hoare 发明,被列为 20 世纪十
* 大算法之一 ,是迄今为止所有内排序算法中速度最快的一种。冒泡排序的升
* 级版,交换排序的一种。快速排序的时间复杂度为 O(nlog(n)) 。
*
* 排序思想:
* 1)从数列中挑出一个元素,称为“基准”(pivot)
* 2)重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准
* 值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,
* 该基准就处于数列的中间位置。这个称为分区( partition )操作。
* 3)递归地( recursive )把小于基准值元素的子数列和大于基准值元素的子数列排序。
* 4)递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好
* 了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代
* (iteration )中,它至少会把一个元素摆到它最后的位置去 。
*
* 通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,
* 则分别对这两部分继续进行排序,直到整个序列有序。
*/
// System.out.println("\n\n数组练习9:快速排序 ");
//
// public class QuickSort {
// private static void swap(int[] data, int i, int j) {
// int temp = data[i];
// data[i] = data[j];
// data[j] = temp;
// }
//
// private static void subSort(int[] data, int start, int end) {
// if (start < end) {
// int base = data[start];
// int low = start;
// int high = end + 1;
// while (true) {
// while (low < end && data[++low] - base <= 0)
// ;
// while (high > start && data[--high] - base >= 0)
// ;
// if (low < high) {
// swap(data, low, high);
// } else {
// break;
// }
// }
// swap(data, start, high);
//
// subSort(data, start, high - 1);//递归调用
// subSort(data, high + 1, end);
// }
// }
// public static void quickSort(int[] data){
// subSort(data,0,data.length-1);
// }
//
//
// public static void main(String[] args) {
// int[] data = { 9, -16, 30, 23, -30, -49, 25, 21, 30 };
// System.out.println("排序之前:\n" + java.util.Arrays.toString(data));
// quickSort(data);
// System.out.println("排序之后:\n" + java.util.Arrays.toString(data));
// }
// }
}
}