java基础day_04整理(方法递归+数组+四大排序:冒泡,选择,插入,快排)

方法

Java是面向对象的语言,对象都会有一些方法,方法其实就是这些类可以做的事情,也称为函数

方法中,一般都会写一些执行了某些功能的代码

将来可以调用这个方法,从而去完成某些想要的功能

方法一般单独声明于类中,方法不可以写在main方法里,否则会报错

语法:

修饰符 返回值类型 方法名 (参数列表){

代码块;

return 返回值;

}

修饰符 : 暂时的写法 public static

返回值类型 :可以是void ,表示没有返回值 ,也可以是数据类型(基本类型和引用类型)

方法名 : 自己取的名字,遵循标识符命名规范

参数列表 :将来调用这个方法时候,是否需要传入值进行运算,如果不需要,可以不写

参数的定义方式 : 数据类型 变量名

代码块 : 将来方法中执行的功能

return :跟返回值类型挂钩

如果有返回值类型,那么就需要return 对应类型的值,

如果没有返回值类型,return可以省略

形参 :定义在方法体的括号中的参数

实参 :调用方法的时候,传入的实际的内容

案例代码如下

public class MethodDemo {
    //写一个方法,调用之后,可以传入2个整数,并完成两个整数的计算求和后返回
    public static int add(int a,int b){
        int sum = a + b; //拿到传入的参数,并计算和
        return sum; //把求和的结果返回
    }
    public static void main(String[] args) {
        //调用方法,
        //也可以将整个方法的表达式参与运算
        System.out.println(add(10, 20));
        // 可以声明一个变量,接收返回的值
        int result = add(10,20);
        System.out.println(result);
    }
}
//方法的其他用法
public class MethodDemo02 {
    public static void main(String[] args) {
        //修饰符  返回值  方法名 (参数列表){
        // 代码块;
        // return;
        // }

        add();
        //调用方法,传入参数的类型不能有错
        add("hello","world");
        //调用有返回值的方法
        //1,要么将方法结果返回给一个变量
        //2,要么将返回值结果,拿过来做运算
        String s = addString();
        System.out.println(addString());

        //调用有参数有返回值的方法

        String s3 = addString("你好", "世界");
        String s1 = "你好";
        String s2 = "世界";
        String s4 = addString(s1, s2);
        System.out.println(s3);
        System.out.println(s4);

    }
    // 没有返回值的方法,一般在方法中,会把要做的事情处理完
    //1,没有返回值,没有参数 ,某些固定的功能,不需要改变的时候使用这种
    public static void add(){
        String s1 = "hello";
        String s2 = "world";
        System.out.println(s1 + s2);
    }
    //2,没有返回值,有参数的情况,一般会根据用户传入的内容,执行对应的功能
    public static void add(String s1,String s2){
        System.out.println(s1 + s2);
    }

    //3,有返回值,没有参数的情况
    public static String addString(){
        //只要有返回值,必须对应有return
        String s1 = "hello";
        String s2 = "world";
        //返回字符串的拼接
        return s1+s2;
    }
    //4,有返回值,有参数的情况
    public static String addString(String s1,String s2){
        return  s1 + s2;
    }

    //形参  :定义在方法体的括号中的参数
    // 实参 :调用方法的时候,传入的实际的内容
}

下面是综合案例展示

public class MethodDemo02 {
    public static void main(String[] args) {
        add();
        String s = methodString("nihao", "shijie");//这里的"nihao", "shijie"是实参,而方法里的s1,s2是形参
        System.out.println(s);


    }

    //修饰符  返回值 方法名 (参数列表){
    // 代码块;
    // return;
    // }

    //方法定义不能放在main方法中,不然会报错

    //没有返回值的方法,一般在方法中,会把要做的事情全部处理完

        //没有返回值和参数的无参方法
        public static  void add(){
            String s1 ="hello";
            System.out.println(s1);
        }
        //没有返回值,有传入参数的有参方法
        //只要有返回值,就有return
        //return的返回值必须跟方法的返回值类型对应(定义一个string类型的方法,返回值如果有则必须为string类型)
        //调用有返回值类型的方法时,要么将方法结果返回给一个定义的变量
        //要么将返回值结果,拿过来做计算
        //返回值结果可以继续参与运算
        //有返回值参数定义新的变量接收可以使用alt+回车
        //有返回值,有参数的有参方法

    public static String methodString (String s1,String s2){
        //定义在方法体中的参数(括号中的)叫形参,即形式参数,不管外界定义了什么参数,
        // 被带入方法体中后就会变成对应的形参s1,s2
        //参与方法体中运算
        //而实参是用户放方法里存入的实际内容,比如要往方法里存入"你好","世界"

        String s3 = s1+s2;
        System.out.println("methodString成功执行,返回两个字符串拼接结果");
        return s3;//将s3字符串作为结果返回
    }

}

方法传参调用小练习(实现输入两个数字进行交换,并输出返回结果(不需要返回值,只需要打印结果))

    //定义一个方法,实现传入 a=? b=?交换之后的a=? b=?

    public static void exchange(int a,int b){
        System.out.println("交换之前的a="+a+" "+"b="+b);
        int temp;
        temp = a;
        a = b;
        b = temp;
        System.out.println("交换过后的a="+a+" "+"b="+b);

    }

    public static void main(String[] args) {


        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int b = scanner.nextInt();

        exchange(a,b);


    }



方法递归(重点)

方法递归其实就是方法在自己的方法体中调用自身

递归在调用的时候,可能会产生栈溢出错误,使用的时候要注意控制递归的次数,而且将来要去指定递归结束的条件

方法递归使用案例如下

//方法递归的使用
public class MethodDemo03 {
    public static void main(String[] args) {
        //方法递归
        //method01();
        int sum = sum01(100);
        System.out.println(sum);
        int sum02 = sum02(100);
        System.out.println(sum02);
    }

    //public static void method01(){
    //    int i = 1;
    //    System.out.println(++i);
    //    method01();
    //}

    //定义一个方法,传入参数n,可以返回1-n之间数值的和
    //普通循环求法
    public static int sum01(int n){
        int sum = 0;
        for (int i = 0; i <= n; i++) {
            sum += i;
        }
        return sum;
    }
    //递归的写法 1+2+3+4+5+...+n
    public static int sum02(int n){
        if (n == 1){
            return 1;
        }
        return n + sum02(n-1);
    }
    // n = 1    sum = 1
    // n = 2     2 + sum02(1)  ==> 2 + 1
    // n = 3     3 + sum02(2)  =>  3 + 2 + 1
    //..
}

递归小练习:青蛙跳级

题目要求如下

一只青蛙一次可以跳上1级台阶,也可以跳上2级。

求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果)

实例代码如下(总结下来每一次青蛙跳级的方法种类数量呈斐波那契数列排序:1,2,3,5,8........)

 public static void main(String[] args) {
        int n=jump(5);
        System.out.println(n);

    }
    
    public static int jump(int n) {
        if (n == 1||n == 2) {
            return n;
        }
    return  jump(n-1)+jump(n-2);
    }
/*分析:
一级     1种  1                            1
二级     2种 1+1  、2                      2
三级     3种  1+1+1、2+1、1+2              1+2=3
四级     5种 1+1+1+1/1+2+1/1+1+2/2+1+1     2+3=5
五级     8种                               3+5=8
............                               .........
n级                                       f(n-1)+f(n-2)
**/

类似常见递归还有求数的阶乘以及一系列斐波那契数列问题(青蛙跳级,兔子繁殖等等)

数组

数组是java学习中一个非常重要的知识点,因此必须要牢牢掌握相关知识。

数组的定义

数组其实也是声明一个变量,跟普通的变量不同的是,可以存储相同数据类型的一组数据

数组是一个长度固定的数据结构

数据也是一个引用数据类型(对象)

数组的声明方式

语法:

步骤一:先声明数组

1、数据类型 变量名[];

2、数据类型[] 变量名;

步骤二:给数组声明空间

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

示例:

int[] array;   或者 int array[];  //推荐使用前一种

array = new int [10];

合并写法:

int[] array=new int[10];

步骤三:给数组的空间赋值,分配空间,根据数组的索引(对应下标)找到对应的空间

array[0]=10;

数组定义并赋值:(已经确定数组内的元素值与数量)

int [] array={2,5,3,2,6,4}

详细的数组定义赋值代码如下

//数组的声明
public class Demo01 {
    public static void main(String[] args) {
        //数组声明:
        // 写法1
        //创建数组,并声明空间,赋值给变量arr
        int[] arr = new int[5];
        //给数组空间赋值
        arr[0] = 10;
        arr[1] = 20;
        arr[2] = 30;
        arr[3] = 40;
        arr[4] = 50;
        //写法2:已知数组的内容。可以简写
        int[] arr1 = new int[]{10,20,30,40,50};
        //写法3 : 再简写
        int[] arr2 = {10,20,30,40,50};

        //使用写法1,声明一个String类型的数组,数组中有5个空间,内容随便写
        String[] strArray = new String[5];
        strArray[0] = "hello";
        strArray[1] = "world";
        strArray[2] = "java";
        strArray[3] = "mysql";
        strArray[4] = "linux";

        //使用写法3,声明一个char类型的数组,数组有5个char类型的值
        char[] charArray = {'a','b','c','d','e'};
    }
}

数组的特征(长度、索引)

长度固定,索引下标从0开始 ,下标的值是 从 0 ~ 长度-1

数组的遍历(循环进行遍历)

public class Demo02 {
    public static void main(String[] args) {
        int[] arr = {10,20,30,40,50};
        //直接输出数组,输出的是数组变量的引用地址
        System.out.println(arr);
        //通过数组下标,将它的值输出
        System.out.println(arr[0]);
        System.out.println(arr[1]);
        System.out.println(arr[2]);
        System.out.println(arr[3]);
        System.out.println(arr[4]);
        System.out.println("------------------------");
        //使用for循环遍历
        //循环的次数 : 跟数组的长度一致
        for (int i = 0; i < 5; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("------------------------");
        //数组中,有一个length属性,可以返回数组的长度
        System.out.println(arr.length); //5
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

         //增强for循环完成数组的遍历
        //for(数据类型 变量  : 数据集合){
        //}
        System.out.println("------------------------");
        for (int i :arr){
            System.out.println(i);
        }
        
        //快捷键 :itar
        for (int i = 0; i < arr.length; i++) {
            int i1 = arr[i];
            System.out.println(i1);
        }
        //iter
        for (int i : arr) {
            System.out.println(i);
        }
    }
     //定义一个方法,调用方法的时候,可以传入一个数组,
    // 然后这个方法可以将数组的内容输出
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

练习

循环录入5个学生的成绩到数组中

录完之后,将5个人的成绩输出,并输出其中的最高分

 public  static void createGetArray(){
        //循环录入五个学生的成绩到数组中,录入之后,将五个人的成绩输出,并输出最高分
        int [] arr3 =new int[5];
        //创建输入对象
        Scanner scanner = new Scanner(System.in);
        //定义一个最高分,用以一会循环赋值后进行比较,获取最高分(需要定义在循环外面)
        int max=0;
        for (int i = 0; i < arr3.length; i++) {

            System.out.println("请输入第"+i+"个学生的成绩:");
            //通过数组下标获取出入的值
            arr3[i]=scanner.nextInt();
            max= max> arr3[i] ? max:arr3[i];//获取最高分
        }
        System.out.println("五个学生的成绩是:");
        ArrayDemo01.printarr(arr3);
        System.out.println("最高分是:"+max);

    }
  public static void main(String[] args) {

     createGetArray();

}

数组的内存分配

1,int[] arr = new int[5] : 表示在内存的堆区申请一个空间,这个空间有5个位置,每个位置的默认值是0,然后将这个区域在内存中的地址,指向变量 arr

2,arr[0] = 10 ; 表示通过 arr对应的地址引用,找到内存中数组的位置空间,通过下标0,找到这个空间中对应下标的值,然后将10 替换掉原有的默认值

image.png

 

二维数组的创建和遍历

二维数组指的是,在数组中,继续存放数组的一种形式(二维数组的每一行就是一个一维数组)

练习

循环录入5个班的成绩(每个班里定义为有五名学生)到数组中

录完之后,将这五个班里每个班的学生总成绩依次输出。

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //定义一个二维数组
        int[][] array =new int[5][5];
        //使用for循环完成成绩录入
        //i班级,j学生
        for (int i = 0; i < 5; i++) {
            System.out.println("这是第"+(i+1)+"个班级");
            for (int j = 0; j < 5; j++) {
                System.out.println("第"+(j+1)+"个学生的成绩:");
                array[i][j]= scanner.nextInt();
            }
        }
        //统计每个班的总成绩
        int sumgrade=0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                sumgrade+=array[i][j];
            }
            System.out.println("第"+(i+1)+"个班的总成绩为:"+sumgrade);
            sumgrade=0;//总成绩要清零,不然输出的总分结果是累加了前面计算的班级的总分
        }
    }

冒泡排序

  • 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
  • 针对所有的元素重复以上的步骤,除了最后一个;
  • 重复步骤1~3,直到排序完成
/*
冒泡排序
 */
public class BubbleSort {
    public static void main(String[] args) {
        //声明一个数组,
        //排序是为了将数组中的数据按照顺序从小到大排列
        int[] arr = {25,36,11,5,2};
        System.out.println("排序前");
        printArray(arr);
      /*  //第一次排序
        for (int i = 0; i < arr.length - 1; i++) {
            //将数组的值做两两比较
            if (arr[i] > arr[i+1]){
                //交换
                int temp= arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第一次排序完:");
        printArray(arr);

        //第二次排序 25 11 5 2 36
        for (int i = 0; i < arr.length-1-1 ; i++) {
            //将数组的值做两两比较
            if (arr[i] > arr[i+1]){
                //交换
                int temp= arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第二次排序完:");
        printArray(arr);
        //第三次排序
        for (int i = 0; i < arr.length-1-1-1 ; i++) {
            //将数组的值做两两比较
            if (arr[i] > arr[i+1]){
                //交换
                int temp= arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第三次排序完:");
        printArray(arr);
        //第四次排序
        for (int i = 0; i < arr.length-1-1-1-1 ; i++) {
            //将数组的值做两两比较
            if (arr[i] > arr[i+1]){
                //交换
                int temp= arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        System.out.println("第四次排序完:");
        printArray(arr);

        for (int i = 0; i < arr.length -1 ; i++) {  //外层循环控制总次数
            for (int j = 0; j < arr.length-i-1 ; j++) {
                if (arr[j] > arr[j+1]){
                   int temp =  arr[j];
                   arr[j] = arr[j+1];
                   arr[j+1] = temp;
                }
            }
        }*/
         bubbleSort(arr);
        System.out.println("排序完:");
        printArray(arr);
    }


    //定义一个冒泡排序的方法:
    public static void bubbleSort(int[] arr){
        for (int i = 0; i < arr.length -1 ; i++) {  //外层循环控制总次数
            for (int j = 0; j < arr.length-i-1 ; j++) {
                if (arr[j] > arr[j+1]){
                    int temp =  arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }


    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
}

选择排序

n条数据,经过n-1趟排序,得到有序结果

  • 开始排序之前,划分一个有序区域,和无序区域
  • 第一次排序开始的时候, 从无序区一个个去寻找最小值,每次找到小的值就做标记,所有数据找完之后,

找到了无序区最小的值,把它移动最前面,作为有序区

  • 继续在无序区找小的值,每一轮都找到一个无序区的最小值,把这个值,依次往有序区的后面排放(

其实是将最小值的位置,和有序区的后一个位置的值做交换)

  • 重复以上第3步
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {33,12,4,56,23,44,74,3};
        System.out.println("排序前:");
        printArray(arr);
        selectSort(arr);
        System.out.println("排序完:");
        printArray(arr);
    }
    //输出方法
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    //写一个选择排序方法
    public static void selectSort(int[] arr){
        //存在一个有序区和无序区
        //排序开始之前,有序区没有内容
        //第一次排序的时候,将第一个数值标记为有序的第一个值
        for (int i = 0; i < arr.length - 1; i++) {
            //指定一个最小数值的索引
            int minIndex = i;
            //从有序区的后面的第一个(i+1)开始遍历
            for (int j = i+1; j < arr.length ; j++) {
                //找到最小的值
                if (arr[j] < arr[minIndex]){
                    //将最小值的下标做交换
                    minIndex = j;
                }
            }
            //循环之后,做数据交换
            if (i != minIndex){
                int temp = arr[i] ;
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
    }
}

插入排序

  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置后;
  • 重复步骤2~5。
插入排序案例:
 public static void main(String[] args) {


    int[] arr ={10,36,5,48,20};
        System.out.println("排序前的数组结果为");
        printArr(arr);
        insertSort(arr);

    }

    //插入排序方法

    public static void insertSort(int[] arr){

        //1.将数组中第一个数当做已经排好的有序区里的一个元素,同时定义一个需要插入的数
        int insert_number;
        //从第二个元素开始(i=1开始 即arr[1])

        for (int i = 1; i <arr.length ; i++) {
            insert_number=arr[i];
                int g=i-1;
                while (g>=0 && insert_number<arr[g]){//插入的数比他前面一个数要小
                    //就把前面区域比他小的数字的下标往后移一位(arr[g+1]与arr[g]数值交换)
                    arr[g+1]=arr[g];
                    //然后g--(从后往前循环对比,把已排序好的区域里的数据从后往前的分别跟目标插入值进行比较
                    // 如果满足while循环,即已排好的里面有值比需要插入的大,则将这个数字往后移动一个)
                    //同时g减一,继续下一个循环(找到下一个在排列有序区里并且比插入值小的数值元素)
                    //因为是从后往前比,所以是g--
                    g--;
                }
                //然后把插入的值赋值给arr[g+1]//将需要插入的数插入到指定位置
            arr[g+1]=insert_number;
            }
        printArr(arr);//调用下面自定义的打印数组函数printArr
        }

        

    public static  void printArr( int [] arr){

        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();//换行
        System.out.println("-------------------------");
    }

了解各个排序的时间复杂度和空间复杂度(各个算法)

快速排序(速度最快的)

public class QuickSort {

    //写一个快速排序的方法
    public static void quickSort(int[] arr,int left , int right){
        //提前声明需要使用的变量
        int  i,j,temp,t;
        //递归结束条件
        if (left > right){
            return;
        }
        //开始排序
        i = left;
        j = right;
        temp = arr[left]; //中间值
        //循环判断
        while (i < j){
            //如果j下标的值,比中间值大,j做--操作
            while (temp <= arr[j] && i < j){
                j--;
            }
            //如果i下标的值,比中间值小,i做++操作
            while (temp >= arr[i] && i < j){
                i++;
            }
            //如果上面两个条件不满足,i 和 j 交换
            if(i < j){
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
        }
        //最后需要将中间值和 j的值做交换
        arr[left] = arr[j];
        arr[j] = temp;
        //递归调用左边
        quickSort(arr,left,j-1);
        //递归调用右边
        quickSort(arr,j+1,right);
    }
    //输出方法
    public static void printArray(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] arr = {10,31,43,2,34,12,4};
        System.out.println("排序前");
        printArray(arr);
        //调用排序方法
        quickSort(arr,0,arr.length-1);
        System.out.println("排序后");
        printArray(arr);
    }
}

排序速度对比

    public static void main(String[] args) {
        Random random = new Random();

        //声明一个长度为100000的数组(10万大小)
        int[] arr =new int[10000];
        for (int i = 0; i < arr.length; i++) {
            //向数组里存入随机的小于10000的数
            arr[i]=random.nextInt(10000);
        }
        //System.currentTimeMillis()可以返回当前时间的毫秒值

        long start = System.currentTimeMillis();
        System.out.println("排序前");
        //调用各个排序方法
//        BubbleSort.boboSort(arr);//14729 -10w  144 -1w
//        InsertSort.insertSort(arr);//1028   -10w    14 -1w
//        SelectSort.selectSort(arr);//4048    -10w     58 -1w
        QuickSort.quickSort(arr,0, arr.length-1);//25 -10w   2  -1w

        System.out.println("排序后");
        long end = System.currentTimeMillis();
     long time = end -start;
        System.out.println("排序花费时长为"+time+"毫秒");
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值