函数在栈中的应用
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);
}
}