2022-07-15 第二小组 张宁杰 java基础(3)
今日重点
查找算法(线性查找、二分法查找),排序算法(冒泡排序、选择排序、插入排序),数组的反转,数组的扩容
学习心得
今日我们接触了简单的Java算法,经过一天的学习,我深深意识到算法研究的难度。虽然我们学习的都是简单基础算法,但其中蕴含的思想是非常值得我们品味和消化的
学习内容
1、数据结构
1.数组
数组是最基本的数据结构,是一张线性表(数据元素间是一一对应的关系,除了第一个和最后一个之外,其余元素都是首尾连接)
2.链表
3.树
4.图
2、写程序的思路和步骤
1.先完成需求的功能
2.根据程序运行的结果进行优化处理
3.代码的重构(让代码量更少)
4.提示效率
3、算法
查找算法
线性查找:简单便于理解
代码实现
int[] arr = new int[]{1, 23, 3, 43, 564};
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数:");
int num = sc.nextInt();
int index = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) {
index = i;
}
}
if (index != -1) {
System.out.println("你要找的数是" + arr[index] + "," + "在目标数组中的下标为:" + index);
} else {
System.out.println("你要找的数是" + num + "," + "在目标数组中是不存在的!");
}
二分法查找:前提是数组必须是排序好的
代码实现
int [] arr = new int[]{1,2,3,4,5,6};
Scanner sc = new Scanner(System.in);
System.out.println("请输入要查找的数字:");
int target = sc.nextInt();
//最左边的下标
int left = 0;
//最右边的下标
int right = arr.length - 1;
if(target < arr[left] || target >arr[right]){
System.out.println(target + "在目标数组中不存在");
}else{
//用来保存找到的下标的值
int res = -1;
while (left <= right){
//找出中间位置
int middle = (left + right) / 2;
if(arr[middle] == target){
//中间的数恰巧就是要找的数
res = middle;
break;
//left = arr.length;
}else if (arr[middle] > target){
//说明我们要找的数在数组的前半区
//如果在前半区,维护left和right,left是不用移动的,right应该移位到中间位置
right = middle - 1;
}else {
//实际上就是arr[middle]<target
//说明在后半区,right是不需要动的,left应该右移到中间位置
left = middle + 1;
}
}
System.out.println("下标是:" + res);
}
排序算法
- 冒泡排序
- 快速排序
- 插入排序
- 选择排序
- 希尔排序
- 堆排序
- 归并排序
- 桶排序
冒泡排序
思路分析:拿第一个数和后面的数一一比较大小,如果第一个数比后面的大,则换位
冒泡排序需要两层循环嵌套:for
外层for循环控制的是需要各个数之间比较几轮
内层的for循环控制的是每个数的真正比较
代码实现
int [] arr = new int[]{12,2544,2324,542,6,77};
for (int i = 0; i < arr.length - 1; i++) {
//已经控制好了比较的次数
//比较的次数 = 数组长度 - 1
for (int j = 0; j < arr.length -1; j++) {
if (arr[j] > arr[j+1]){
//如果前面的比后面的大,换位
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.print("第" + (i+1) + "轮的比较结果是:");
for (int i1 : arr){
System.out.print(i1 + " ");
}
System.out.println();
}
除此之外,还可用JDK的Arrays.sort(arr)函数进行快速排序
选择排序
选择排序是一种简单直观的排序算法,其基本原理是每一次从待排序的数组里找到最小值(最大值)的下标,然后将最小值(最大值)跟待排序数组的第一个进行交换,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。反复的进行这样的过程直到待排序的数组全部有序。
代码实现
int [] arr = new int[]{1,25,48,12,10,-8,127,56};
for (int i = 0; i < arr.length; i++) {
//假设最小数的下标
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]){//找到了最小值
minIndex = j;//保存最小值的下标
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
System.out.print("第"+(i+1)+"次的比较结果是:");
for (int ii: arr) {
System.out.print(ii + " ");
}
System.out.println();
}
文字分析
第一轮:
i=0,minIndex=0,里层的for循环int j = 1;j<8;
if(arr[0] > arr[1]){},由于if不满足,则继续下一次的比较
j = 2,if(arr[0] > arr[2]){},由于if不满足,则继续下一次的比较
j = 3,if(arr[0] > arr[3]){},由于if不满足,则继续下一次的比较
j = 4,if(arr[0] > arr[4]){},由于if不满足,则继续下一次的比较
j = 5,if(arr[0] > arr[5]){},由于if满足条件,执行了minIndex
j = 6,if(arr[5] > arr[6]){},由于if不满足,则继续下一次的比较
j = 7,if(arr[5] > arr[7]){},由于if不满足,则继续下一次的比较
到此为止,里层的for循环执行完毕。minIndex = 5
........
插入排序
插入排序法,就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。插入排序法主要的回圈有两个变数:i和j,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。
代码实现
int [] arr = new int[]{1,25,48,12,10,-8,127,56};
//定义参照物
int current;
for (int i = 0; i < arr.length -1; i++) {
current = arr[i + 1];
//定义上一个元素的下标
int preIndex = i;
//当上一个数的下标有效不能小于0
//并且还要保证当前的数比他上一个数小
//这时候才能让当前数向前移位
while (preIndex >=0 && current < arr[preIndex]){
//移位
//前面的数后移一位
arr[preIndex + 1] = arr[preIndex];
//
preIndex--;
}
arr[preIndex + 1] = current;
}
for (int i : arr) {
System.out.print(i + " ");
}
文字分析
第一轮:
i = 0,current = arr[1],int preIndex = 0
while(0 >= 0 && 25 < arr[0]){}不成立。while循环不启动
arr[0+1] = arr[0+1]
第二轮:
i = 1 ,current = arr[2] =48,int preIndex = 1
while(1 >= 0 && 48 <25){}成立。while循环启动
arr[1 + 1] = arr
........
数组的反转
代码实现
int [] arra = new int[]{1,25,48,12,10,-8,127,56};
for (int i = 0;i < arra.length/2;i++){
//temp存储的是最后一位
int temp = arra[arra.length - 1 - i];
arra[arra.length - 1 - i] = arra[i];
arra[i] = temp;
}
for (int i: arra) {
System.out.println(i+" ");
}
//Arrays是操作数组的一个工具类
数组的扩容
代码实现
int [] nums = new int[]{3,4,6};
//定义一个新的临时数组
int [] temp = new int[6];
for (int i = 0; i < nums.length; i++) {
temp[i] = nums[i];
}
nums = temp;
System.out.println(Arrays.toString(nums));