数组&方法
1 数组的练习
1.1 数组的排序
1.1.1 冒泡排序
public static void main(String[] args) {
int[] arr = new int[]{4,3,6,7,1,8,2};
// 使用冒泡排序法进行排序
for (int i = 0;i < arr.length - 1;i++){// 轮数
System.out.println("i = " + i);
for (int j = 0;j < arr.length- i - 1;j++) { //次数
System.out.println("j = " + j);
if (arr[j] > arr[j + 1]){
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
1.1.2 选择排序
public static void main(String[] args) {
// 选择排序
int[] arr = new int[]{4,3,6,7,1,8,2};
for (int i = 0;i < arr.length - 1;i++){ //轮数
System.out.println("i = " + i);
for (int j = i + 1;j < arr.length;j++){
System.out.println("j = " + j);
if (arr[i] > arr[j]){
// 交换数据
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
时间复杂度:代码执行的次数
空间复杂度:代码执行过程中临时占用内存的量度。
工作中的排序方式
Arrays.sort(arr);
1.2 数组的扩容(缩容)
数组的内存是连续的。
- 数组扩容方式一
// 数组的扩容 方式一
int[] arr = {1,2,3,4,5};
int[] arr1 = new int[2 * arr.length];
// 参数1:要拷贝的数组
// 参数2: 要从哪个索引开始拷贝数组
// 参数3: 要拷贝到哪一个数组
// 参数4: 拷贝的目标数组的开始索引
// 参数5: 要拷贝的元素的个数
System.arraycopy(arr,0,arr1,0,5);
arr = arr1;
System.out.println(Arrays.toString(arr));
- 数组扩容方式二
// 数组的扩容方式二
int[] arr = {1,2,3,4,5};
System.out.println(arr);
// 参数一: 要拷贝的数组
// 参数二: 扩容后的长度
arr = Arrays.copyOf(arr,arr.length * 3);
System.out.println(arr);// 地址不同 说明是新创建一个数组扩容了
System.out.println(Arrays.toString(arr));
2 方法
2.1 方法的基本使用
方法本质上就是一个代码块,进去的数据是参数,出来的数据是返回值。
方法的定义格式:
修饰符 返回值类型 方法名称(参数类型 参数名称,参数类型 参数名称...){
方法体;
return 返回值;
}
- 修饰符:目前记住就是public static
- 返回值类型:经过方法的代码,最终返回的结果值的类型
- 方法名称:和定义变量的规则一样 findUserById
- 参数类型:传入方法中的数据类型(相当于变量的数据类型)
- 参数名称: 参数的标识符 相当于一个变量的名称
- 方法体:方法中具体的代码
- return: 1 立即结束方法 2将最终的结果(返回值)交给方法的调用者。
- 返回值:方法的最终结果
方法不会自动执行,需要对方法进行调用才能执行
方法不可以嵌套
方法的执行和方法的定义顺序无关。
// 定义两个整数的求和方法
public static int sum(int a,int b){
// 求和后的结果
int result = a + b;
return result;
}
方法的调用:
格式: 方法名(参数);
哪一行调用就会把结果返回到哪一行
2.2 void修饰
如果一个方法不需要返回值,那么可以使用void修饰.
// 定义一个方法,在控制台输出打印100次HelloWorld
// void 代表方法没有返回值 而且可以省略方法中的 return
public static void printHello(){
for (int i = 0; i < 100; i++) {
System.out.println("HelloWorld");
}
}
练习:定义一个方法,判断一个数字是否是奇数
// 定义一个方法,判断一个数字是否是奇数
public static boolean isOdd(int a){
// if (a % 2 != 0){
// return true;
// }
// return false;
return a % 2 != 0;
}
2.3 方法的重载
在一个类中,允许参数列表不同的同名的方法存在,就是方法的重载
只要在调用时能够区分开要调用的是哪一个方法,就允许重载。
参数列表不一样的情况:
- 参数个数不同
- 参数的数据类型不同
- eg: sum(double a,double b) sum(int a,int b)
- 多个参数的情况下,参数的数据类型顺序不同
public static void main(String[] args) {
//只要调用时能够分清到底要调用哪一个,就允许重载
System.out.println(sum(10.7,20));
}
// sum(int,double)
public static int sum(int a,double b){
return 1;
}
// sum(double,int)
public static int sum(double a,int b){
return 2;
}
- 重载和参数名称无关
- 重载和返回值类型无关
2.4 参数传递问题
2.4.1 基本数据类型(包含String)作为参数传递
- 形式参数(形参):在方法定义时,在小括号中的参数。
- public static int sum(int a,int b){…}
- 实际参数:(实参):在方法调用时,传入小括号的参数。
对于基本数据类型(String),形式参数的操作不会影响实际参数。
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a);// 10
System.out.println(b);// 20
change(a,b);
System.out.println(a);// 10
System.out.println(b);// 20
}
public static void change(int x,int y){
x *= 10;
y *= 10;
System.out.println(x);// 100
System.out.println(y);// 200
}
2.4.2 引用数据类型(不包含String)形式参数的改变会影响实际参数
public static void main(String[] args) {
// 定义数组
int[] arr = {10,20,30};
System.out.println(arr[0]);// 10
System.out.println(arr[1]);// 20
System.out.println(arr[2]);// 30
change(arr);
System.out.println("=======");
System.out.println(arr[0]);// 100
System.out.println(arr[1]);// 200
System.out.println(arr[2]);// 300
}
public static void change(int[] array){
array[0] *= 10;
array[1] *= 10;
array[2] *= 10;
System.out.println(array[0]);// 100
System.out.println(array[1]);// 200
System.out.println(array[2]);// 300
}
2.5 方法的递归(recursion)
在方法中调用自身的方法,可以将复杂的业务逻辑看作一个个小的业务逻辑的循环。递归一定要给程序出口,保证递归一定次数后可以结束方法,否则会出现栈溢出错误(StackOverflowError).
public static void main(String[] args) {
System.out.println(sum(10));
}
// 传入一个n的值,求1-n的和
/**
* sum(10) = 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1
* sum(10) = 10 + sum(9);
* 9 + sum(8)
* 8 + sum(7)
* ....
* 2 + sum(1)
*
*/
public static int sum(int num){
// 程序的出口
if (num == 1){
return 1;
}
return num + sum(num - 1);
}
3 综合练习
- 百钱买百鸡
3文钱可以买1只公鸡,2文钱可以买一只母鸡,1文钱可以买3只小鸡。用100文钱买100只鸡,那么各有公鸡、母鸡和小鸡多少只?
public static void main(String[] args) {
// 百钱买百鸡
for (int a = 0;a <= 33;a++){ // 最多33只公鸡
for (int b = 0;b <= 50;b++){//最多50只母鸡
for (int c = 0;c <= 100;c++){// 最多100只小鸡 因为超过100只不符合题意
// 判断c是否是3的倍数 因为一文钱买3只小鸡
if (c % 3 != 0) continue;
// 花的总钱
int sumPrice = a * 3 + b * 2 + c / 3;
if ((sumPrice == 100) && ((a + b + c) == 100)){
System.out.println(a + "只公鸡," + b + "只母鸡," + c + "只小鸡");
}
}
}
}
}
- 不死神兔
有一对兔子,从出生后的第三个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子。假设兔子都不死,问三十个月后兔子的对数是多少?
public static void main(String[] args) {
int[] array = new int[30];
array[0] = 1;
array[1] = 1;
for (int i = 2;i < array.length;i++){
array[i] = array[i - 1] + array[i - 2];
}
System.out.println("第三十个月的兔子对数是" + array[29]);
}
- 汉诺塔问题【了解】
来源于印度的一个神话故事。有三个金刚石塔,第一个从小到大摆着64片黄金圆盘。现在把圆盘按大小顺序重新摆放到最后一个塔上。并且规定,在小圆盘上不能放大圆盘。在三个塔之间一次只能移动一个圆盘。
要求将64个黄金圆盘最理想的移动轨迹打印在控制台上。
public static void main(String[] args) {
hanio(64,'A','B','C');
}
// 汉诺塔问题
// 定义一个方法,实现汉诺塔移动问题
// n代表的是圆盘的数量
// A: 代表需要移动盘子的柱子
// B: 代表的是辅助的柱子
// C: 代表需要将盘子移动到的柱子
public static void hanio(int n,char A,char B,char C){
if (n == 1){
System.out.println(A + "--->" + C);
}else {
hanio(n-1,A,C,B);
System.out.println(A + "--->" + C);
hanio(n-1,B,A,C);
}
}
``