目录
心情感悟
今天的排序算法是真的麻烦,学着学着就烦了,但还是硬听。老师讲的很细,还好笔记跟的好,所以在这里建议大家真的真的要写好笔记,每一个记录反复看就变成了一个必会的知识点;还有今天的作业(巨难),刚开始思路不清晰卡了半个小时,后来有了整体思路就能越来越顺手了,在建议大家现有一个整体框架再去一步一步写代码,还有做一部分就要代码运行一下,纠错,否则和我一样最后在运行,出现bug难找难改,两个小时就没了。。。。总的来说今天学的还不错,一开始有点自闭,但后来都通了,感觉很爽。
本次重点:算法+数据结构
数据结构
1.数组:是最基本的数据结构。是一个线性表(数据元素之间是一对一的关系,除了第一个和最后一个之外,其他元素都是首尾链接的)
2.链表:是一种常见的基础数据结构,链表是一个功能极为强大的数组
3.树
4.图:深度遍历、广度遍历
写程序思路
1.先完成需求的功能
2.根据程序运行的结果进行优化
3.研究代码的重构
4.提升效率
查找算法
线性查找
/*练习
找出一个数在数组中位置:
在数组中是否存在,如果存在,返回下标,如果不存在,输出-1
如果找到了,把下标i保存起来,显示你要找的数是xxx,在目标数组中的下标是xxx
如果没找到,则显示你要找的数是xxx,在目标数组中不存在
*/
int [] arr = new int[]{1,52,47,56,85,-4};
Scanner sc = new Scanner(System.in);
System.out.println("请输入您要找的数字:");
int num = sc.nextInt();
int index = -1;
//初始化条件定义在for循环外的情况:但尽量别用
int i = 0;
for (;i < arr.length;i++){
if (num == arr[i]){
index = 1;
break;
}
}
if (index != -1){
System.out.println("您要找的数字是:" + num + "在目标数组中的下标是" + i);
}else{
System.out.println(System.out.println("您要找的数字是:" + num + "不在目标数组中");
}
二分法查找
1.如果要使用二分法查找来找数字,前提是这个数组必须顺序
int [] arr = new int[]{1,2,3,4,5,6,7};
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;
}else if (arr[middle] > target){
/*
说明我们要找到数在前半区
维护left、rigjt
left不需要动
right应该移动到中间位置
*/
right = middle - 1;
/*为什么-1?
因为已经知道中间值不是我们要找的数,所以可以把中间的数跳过去
*/
}else {
/*条件就是arr[middle] < target
说名要找的数在后半区
right不需要动
left该向右移动到中间位置
*/
left = middle + 1;
/*
为什么+1?
因为已经知道中间值不是我们要找的数,所以可以把中间的数跳过去
*/
}
}
}
排序算法
常见:
1.冒泡排序
2.插入排序
3.选择排序
4.快速排序(巨难)
不常见:
5.希尔排序
6.堆排序
7.归并排序
8.桶排序
写程序:网页 并不难
难的是底层,优化,需分析
*冒泡排序
从小到大思路分析:
1.先拿第一个数和第二个数比较大小,大的数在后不换位,大的数在前则换位,再用大的数和下一位比较,大的数
在后不换位,大的数在前则换位,以此类推,直到最大的数变成最后一位,称第一次比较结束,此时最大的数在
最后,可以不参与下次比较(内部循环)
2.一共进行的比较次数为数组长度减一(外部循环)
冒泡排序需要两层循环嵌套:for为例
1.外层for循环控制各个数之间的比较
2.内层for循环控制的是每个数真正的比较、换位
int [] arr = new int[]{1,52,47,56,85,-4};
for (int i = 0;i < arr.length - 1;i++){
//已经控制好比较次数
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]){
//如果前面的比后面的大,换位
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第" + (i + 1) + "轮比较的结果是:");
for (int i1 : arr){
System.out.println();
}
break;
}
从大到小排序:
把if循环条件表达式的 “<” 改成 “>” 即可
排序的简便写法(只能从小到大):
public static void main(String[] args) {
int [] arr = new int[]{1,52,47,56,85,-4};
Arrays.sort(arr);
for (int i : arr){
System.out.println(i);
}
}
选择排序
从小到大思路分析:
1.设数组第一个值为最小值,与后面的数一一比较,储存最小值然后把最小值与第一位 换位(内部循环),下一次循环从数组的第二位开始。
2.一共进行的比较次数为数组长度减一(外部循环)
第一轮
i=0,minIndex=0,里层的for循环int j = 1;j < 7;
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 = 5.
j = 6,if(arr[5] > arr[6]){}。由于if不满足,则继续下一次的比较。
j = 7,if(arr[5] > arr[7]){}。由于if不满足,则继续下一次的比较。
到此为止,里层的for循环执行完毕。minIndex = 5。执行的
int temp = arr[5];
arr[5] = arr[0];
arr[0] = temp;
i=0的这次外层循环执行完毕。
数组变成了-8、25、48、12、10、1、127、56
第二轮
i=1,minIndex = 1,
j = 2,if(arr[1] > arr[2]){}。由于if不满足,则继续下一次的比较。
j = 3,if(arr[0] > arr[3]){}。由于if满足,minIndex = 3;
j = 4,if(arr[3] > arr[4]){}。由于if满足,minIndex = 4;
j = 5,if(arr[4] > arr[5]){}。由于if满足,minIndex = 5;
j = 6,if(arr[5] > arr[6]){}。由于if不满足,则继续下一次的比较。
j = 7,if(arr[5] > arr[7]){}。由于if不满足,则继续下一次的比较。
到此为止,里层的for循环执行完毕。minIndex = 5。执行的
int temp = arr[5];
arr[5] = arr[1];
arr[1] = temp;
数组变成了-8、1、48、12、10、25、127、56
。。。
int [] arr = new int[]{1,25,48,12,10,-8,127,56};
//为什么arr.length不减一?
// 少比一位
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 i1 : arr){
System.out.println(i1 + "、");
}
System.out.print(i + "、");
}
}
插入排序
从小到大思路分析:
假设这个数组是一个从小到大排序的,将第一个元素作为参照物,和后面的数一一比较,把比参照物大的数插入到参照物前面。
int [] arr = new int[]{1,52,47,56,85,-4};
//定义参照物
int cunrrent;
for (int i = 0; i < arr.length - 1; i++) {
cunrrent = arr[i + 1];
//定义参照物上一个元素的下标
int preIndex = i;
//当上一个数的下标有效(不小于0),并且还要保证当前的数比它上一位的数小,才能让当前数向前移动
while (preIndex >= 0 && cunrrent < arr[preIndex]){
//移动位置
//前面的数往后移一位
arr[preIndex + 1] = arr[preIndex];
//
preIndex--;
}
arr[preIndex + 1] = cunrrent;
}
for (int i : arr) {
System.out.print(i + "、");
}
数组的反转
思路1:
在创建一个等长的数组,把当前输入的每一个元素倒着填入到新数组中,在赋值给老数组
思路2:
利用交换的方式,将第一位与最后一位交换,第二位与倒数第二位交换,以此类推
Arrays是操作数组的工具类
思路1:
int [] arr = new int[]{1,25,48,12,10,-8,127,56};
int [] arr2 = new int[arr.length];
for (int i = 0;i < arr.length;i++){
//将arr的下角标对应的数,赋值给arr2的反向下角标
arr2[arr.length - 1 - i] = arr[i];
}
arr = arr2;
for (int i : arr){
System.out.print(i + "、");
}
思路2:
int [] arr = new int[]{1,25,48,12,10,-8,127,56};
for (int i = 0; i < arr.length / 2; i++) {
//temp存储的最后一位
int temp = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = arr[i];
arr[i] = temp;
}
for (int i : arr){
System.out.println(i);
}
数组的扩容
定义一个新数组,把原数组赋值到新数组,新数组再赋值给原数组。
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));
作业
要求
Scanner sc = new Scanner(System.in);
System.out.println("欢迎使用员工管理系统:");
System.out.println("请选择功能:1、添加员工 2、查询员工 3、修改员工 4、删除员工(选做)");
String flag = sc.next();
int id = 1001;
switch (flag){
case "1":
System.out.println("请输入员工姓名:");
String name = sc.next();
/*
员工信息要保存到数组里。
1.工号(不能输入,自动生成的自动递增的一个数字1001)
2.员工姓名
员工的工号和姓名都是保存到数组里(可以用二维数组:难,有数据类型问题)
int [] nos = new int[2];(nos[0]=id,name[0]=.. )
String [] names = new String[2];
当数组人满之后0要考虑扩容问题
*/
case "2":
/*
根据工号查询(输入工号,在nos数组中找到并返回下标,根据下标在name中找名字输出,可以用二分法,线性查找)
如果有能力的同学。可以去做根据姓名查询,姓名可以重名(选坐)
*/
/*选做:
排序,根据工号倒序(从大到小)排序,姓名也倒过来
*/
case "3":
/*
修改有两个操作:
先输入员工号,(员工号不能改,该员工名。)先查询员工号在不在,如果不在,
员工号输入有误,
如果在,先显示出原有信息,请输入新的名字,
修改信息。1002 nos[1] names[1]=
*/
case "4":
/*
数组删除元素;
有10个元素,如果删除第5个,移位的问题
int[] 数组删除值相当于值为0
String[] 数组删除值相当于值为null
*/
default:
//死循环:是否继续
}