带你走进java-第四章.函数与栈,数组与堆,冒泡排序,选择排序,折半查找

函数在栈中的应用

 1. 栈内存
    特点:
    1.所有的函数都在进入栈内存中执行,当函数执行完毕时 会自动出栈并延时销毁.
    2.先入栈的后出栈.
    入栈(又称压栈)
    出栈(又称弹栈)

这里写图片描述

数组之一维数组

1.概念:
  保存一组 相同数据类型的元素
2.三种声明方式:
 声明方式 1️⃣数组中的元素数据类型[] 数组名 = new 数据类型[数组长度];

    //注意:数组的长度一旦确定,就不能更改
    //!!!!!关键词new  表示会从堆内存中开辟一块空间
    //  数组会在堆内存中 开辟一块连续的内存空间

数组在堆内存的应用

堆内存特点:
1.堆内存会分配内存地址
2.堆内存会分配 初值
数组类型为基本数据类型 初值0
数组类型为引用数据类型 初值null
3.有垃圾回收机制
(这块内存没人用,就是垃圾)

    // 举例:声明一个数组,能保存五个int元素
int[] array = new int[5];//代表保存元素的个数
    //如何给数组中的元素赋值?
    //使用下标来进行对数据元素的赋值和取值
    //下标从0开始
    //数组名[下标] = 值;
    //一般数组在 = 左边是赋值;在 = 右边是取值
array[3] = 10;
**如果赋值的元素不存在数组中**
// ArrayIndexOutOfBoundsException
// 下标越界异常
 array[5] = 15;
**如果将数组赋值null**
//把array保存的地址  指向空
        array = null;

// NullPointerException(空指针异常)
// 再次赋值时会报错,提示:访问了一块不属于你的内存区域
        array[3] = 3;
 声明方式   2️⃣int[] array = new int[] {1,2,3,4,5};
 声明方式   3️⃣( 语法糖 )
       int[] array1 = {1,2,3,4,5};

打印数组

1.遍历数组打印
先获得数组长度,再循环遍历数组
for (int i = 0; i < array1.length; i++) {
        System.out.println(array1[i]);
    }
2.直接打印数组的所有元素   
// Arrays是数组工具类(带s的基本都是工具类)
System.out.println(Arrays.toString(array));

//练习1:需求: 随机10个数 随机的区间为[15,150]
//       1.把这个10个数放入数组中
//       2.打印最大值/最小值

//声明空的 长度为10的数组
int[] arr = new int[10];
//声明最大值
int max = 0;
//声明最小值
int min = 151;
//遍历数组
for(int i = 0;i< 10;i++){
    int num = (int)(Math.random()*186+15);
    arr[i] = num;
    if(max < arr[i]){
        max = arr[i];
    }
    if(min > arr[i]){
        min = arr[i];
    }
}
System.out.println("max = " + max);
System.out.println("min = " + min);


----------


//练习2.根据下标查找元素
//     需求: 封装一个函数 传入数字1 返回 一
//     数字2 返回 二 ….. 数字5 返回 五  为止

public static char findkeytoindex(int index){
    char[] arr = new char[]{'一','二','三','四','五'};
    return arr[index - 1];//不需要遍历,直接可以返回
}

//练习3.根据元素寻找下标
//     需求: 
//     定义一个数组 数组值 分别 3,6,11,22 
//     在数组中 查找 11的位置

public static int findindextokey(int key){
        int[] arr = new int[] {3,6,11,22};
        int index = -1;//!一定要定义一个变量储存下标,下标只能在循环中生效
        for(int i = 0;i < arr.length ;i++){
            if(key == arr[i]){
                index = i;
                break;
            }
        }
        return index;
    }

元素的反转 (函数中)

//练习.
    // 数组元素交换 1,2,3,6,8->8,6,3,2,1
    // 交换几次?   =   数组长度/2
    // 谁和谁交换?  
    //array[0]----->array[ length-1 -0 ];
    //array[1]----->array[ length-1 -1 ];
    //array[2]----->array[ length-1 -2 ];
    //array[i]----->array[ length-1 -i ];
    int[] arr = new int[] {1,2,3,6,8}
    int num = arr.length/2;
    for(int i = 0; i < num ; i++){
        int temp = arr[i];
        arr[i] = arr[length - 1 - i ];
        arr[length - 1 - i]=temp;
    }

// 基础数据类型(int)  参数传递时  是  值的传递 
(所以要在函数外打印 改变数据的时候,函数要返回值)
  int a = 10;
  int b = 15;
// 交换两个变量的值(过程变成函数)
  int c = a;
  a = b;
  b = c;
//!!!!如果是在函数中已经交换了,但只是值改变了.
//但是下面打印的还是(a = 10,b = 15),而不是(a = 15, b = 10);详见上面
System.out.println("a = " + a + "," + "b =" + b);  
//引用数据类型(数组)   参数传递时  是  地址的传递
(所以在函数中改变了之后,在外面打印会改变)
public static void reverse(int[] array) {
    //计算交换次数
     int num = array.length/2;
    //遍历数组
    for (int i = 0; i < num; i++) {
        int temp = array[i];
        array[i] = array[array.length - 1 - i];
        array[array.length - 1 - i] = temp;
    }
    //System.out.println(Arrays.toString(array));
}

算法之冒泡排序

核心思想:交换两个相邻元素的位置
     *   每一次进行全组的比较  都确定了一个极值放在最右边,一共 n(length)-1 次比较  //找到n个极值
     *   每一次全组比较  比较次数为 n-1-极值个数(减少比较次数);  //n个极值依次放到最右边
     * 举例:{3 , 2 , 5 , 1}排序
     * 第一次全组比较(次数为4-1-0)
     * 3  2  5  1
     * 2  3  5  1
     * 2  3  1  5
     * 第二次全组比较
     * 2  3  1  5  
     * 2  1  3  5
     * 第三次全组比较
     * 1  2  3  5

private static void BubbleSort(int[] arr) {
        // 多次循环,进行排序,依次将 剩余的最大数 排在右边 (控制比较趟数)   
        // 外层循环-1 表示  4个数比3次
        for(int j=0;j<arr.length-1;j++){
            // 依次循环,找出最大,排到最右边 (控制一趟比较次数)
            // 内层循环 -1     表示防止角标越界 
            //( -j是为了 去除 已经比较出来的最大数,可以减少接近一半的比较次数)
            for(int i=0;i<arr.length-1-j;i++){
                 //两两比较,较大值在右边
                if(arr[i]>arr[i+1]){
                    int temp=arr[i];
                    arr[i]=arr[i+1];
                    arr[i+1]=temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

算法之选择排序

 核心:选择一个数(一般选择第一个数) 与其他的数进行比较交换

     举例:{3  2  5  1}排序
     第一次比较:
      2  3  5  1
      2  3  5  1
      1  3  5  2
     第二次比较
      1  3  5  2
      1  2  5  3
     第三次比较
      1  2  3  5
//选择排序
public static void SelectionSort(int[] arr) {
    //外循环 控制比较趟数(arr.length-1)  每次确定一个极值在最左边
    //外循环-1  4个数比3次
    for (int i = 0; i < arr.length-1; i++) {
        //内循环 i+1;  每一趟确定一个数,那个数就不用再重复比较了  
        for (int j = i+1; j < arr.length; j++) {
            if(arr[i] > arr[j]) {
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }   
        }
    }
    System.out.println(Arrays.toString(arr));
}

对半查找

折半查找(在数组中根据元素查找对应的角标)
 前提:必须在有序的数组中查找

 举例:查找11对应的角标
 {1,11,22,33,44,55,66,77,88,99}

 编程思路:
 先把你能想到的 所有变量 声明出来
public static int BinarySearch(int[] arr,int key) {
        // 声明最大最小角标
        int min = 0;
        int max = arr.length - 1;   
        // 折半角标
        int mid = (min + max) / 2 ;
        // 循环查找
        // 明确的循环结束条件:
        // 中间角标对应的值 和 要查找的值相等 循环停止
        while(arr[mid] != key) {
            // 挪动角标
            if (key < arr[mid]) {
                max = mid - 1;
            } else {
                min = mid + 1;
            }
            // 重新计算中间角标
            mid = (min + max) / 2 ;
            // 判断该数组有没有这个值的情况
            if (min > max) {
                // 确定数组中没有这个值
                mid = -1;
                // 停止循环
                break;
            }
        }
        return mid;
    }

外部调用:
    int[] arr = new int[] {1,11,22,33,44,55,66,77,88,99};
        int num = BinarySearch(arr,1);//返回mid值
        if (num == -1) {
            System.out.println("数组中不存在这个值");
        }else {
            System.out.println("该数在数组中的下标是" + num);
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_35368276/article/details/81985513