2022-07-15 第一小组 张明旭 Java基础学习记录

目录

心情

本次重点:算法+数据结构

数据结构

写程序思路​​​​​​

查找算法

线性查找

二分法查找

排序算法

        常见:

        不常见:

        *冒泡排序

选择排序

插入排序

数组的反转

数组的扩容

作业     


心情感悟

 今天的排序算法是真的麻烦,学着学着就烦了,但还是硬听。老师讲的很细,还好笔记跟的好,所以在这里建议大家真的真的要写好笔记,每一个记录反复看就变成了一个必会的知识点;还有今天的作业(巨难),刚开始思路不清晰卡了半个小时,后来有了整体思路就能越来越顺手了,在建议大家现有一个整体框架再去一步一步写代码,还有做一部分就要代码运行一下,纠错,否则和我一样最后在运行,出现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:
//死循环:是否继续
        }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值