zoukankan      html  css  js  c++  java
  • 20172332 2017-2018-2 《程序设计与数据结构》第五周学习总结

    20172332 2017-2018-2 《程序设计与数据结构》第五周学习总结

    教材学习内容总结

    第九章 排序与查找

    查找

    • 1.查找:是一个过程,有两个作用:①确定该组中是否存在该目标元素。②在某个项目组(查找池)中寻找某一指定目标元素。
    • 2.查找算法:①线性查找。②二分查找。为了高效的完成查找,需要最小化比较操作的次数,与查找池中项目的数目息息相关。
    • 3.为了查找到某个对象,需要进行比较对象的操作,因此所涉及的元素实现了Comparable接口。
    • 4.有一个Searching类,所有的排序和查找方法都将位于这个类中。但是这个类使用时必须先实例化,对只含有方法而无其他内容的类很不方便,因此需要把所有方法声明为静态或泛型的。
    • 5.静态方法(类方法):不需要实例化能直接使用的方法,用static修饰符修饰。
    • 6.泛型方法:创建一个引用泛型的方法,泛型参数只应用于该方法。
    • 7.创建泛型方法的方法:只需在方法头的返回类型前插入一个泛型声明即可。其格式是:修饰符 <类型参数列表> 返回类型 方法名(形参列表) { 方法体 }。例如:
      `public static <T, S> int func(List list, Map<Integer, S> map) { ... }
      泛型声明必须在返回类型之前
    • 8.线性查找法:从一端开始依次按顺序搜索查找池,直至另一端。
    • 9.二分查找法(折半查找法):查找池中的项目组已排序,效率比线性查找法高的多。
    • 10.有关二分查找法的相关内容以及ASL的计算方法
    • 11.查找算法的比较:二分查找具有一个对数算法且具有时间复杂度O(log2n),线性查找具有线性时间复杂度O(n),因此二分查找要快的多。但是线性查找的代码实现比二分查找的简单并且线性查找不需要把查找池中的项目组先排序,剩下了额外成本。
    • 12.n越大,二分查找越适用。

    补充知识:

    • 13.分块查找:是折半查找和顺序查找的一种改进方法,分块查找由于只要求索引表是有序的,对块内节点没有排序要求,因此特别适合于节点动态变化的情况。分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。
    • 14.分块查找步骤:①先选取各块中的最大关键字构成一个索引表;②查找分两个部分:先对索引表进行二分查找或顺序查找,以确定待查记录在哪一块中;然后,在已确定的块中用顺序法进行查找。

    • 15.哈希表
    • 16.平方取中法
    • 17.折叠法
    • 18.除留余数法:用关键字k除以不大于散列表长度的数m所得余数作为哈希地址,即H(k)= k % m。(需要注意m的选取,避免产生冲突,不容易产生同义词)。装填因子α最好在0.60.9之间,m最好去1.1n1.7n之间的一个素数,n为散列表中元素个数。
    • 19.解决冲突的方法:
      • ①开放定址法:【(1)线性探测再散列。(2)二次探测再散列。(3)伪随机探测再散列。】查找时若发现有冲突,需要判断用的什么方法,按照方法步骤继续查找。
      • ②再哈希(再找一个哈希函数)。
      • ③链地址法(运用链表,把同义词传在一起,挂在相应的地址下)。查找时就用链表查找操作。

    排序

    • 1.排序:是一个过程,基于某一标准或升序或降序按某个规定的顺序排列。
    • 2.排序算法:①顺序排序。②对数排序。与查找算法一样,在n较小时两类算法间的差别较小。
    • 3.顺序排序:①选择排序法。②插入排序法。③冒泡排序法。
    • 4.对数排序:①快速排序法。②归并排序法。
    • 5.选择排序法:扫描整个列表找出最小值,将这个值与该列表第一处交换,再扫描剩下的列表找出最小值,将它与整个列表的第二处交换,以此类推。(代码需要用一个temp变量暂时存储最小值)

    • 6.插入排序法:通过反复地将某一特定值插入到该列表某个已排序的子集中来完成对列表值的排序。也就是先比较第一个数和第二个数,把第一个数和第二个数排好序之后,把第三个数与已排好的第一个数和第二个数进行比较然后插入进合适的位置,依此类推排完列表中的所有数。
    • 7.冒泡排序法:通过重复比较列表中的相邻元素,并在它们彼此不符顺序时将它们互换来完成对值的排序。也就是先把最大或最小的数放在恰当位置,之后再冒泡出倒数第二个值。
    • 8.快速排序法:通过使用一个任意选定的分区元素将该列表分区,然后对分区元素的任一边的子列表进行递归排序。
    • 9.归并排序法:通过将列表递归式分成两半直至每一子列表都只含有一个元素,然后将这些子列表按顺序重组。(若是奇数,则分解是后面比前面多一个。)

    • 10.基数排序法:基于排序关键字(排序基于某个特定的值)的结构。(就是先创建基数的队列,然后把数放进相应的队列中,通过不断的遍历找到最后的位置)

    • 11.基数:排序关键字的可能取值的个数(也就是每种排序关键字都会单独创建一个队列,最后的队列个数)。

    教材学习中的问题和解决过程

    • 问题1:<T extends Comparable> 和 <T extends Comparable<? super T>> 有什么不同
    • 问题1解决方案:

    • 总结一下就是<T extends Comparable<? super T>>T的实例类型更多了,包括了父类。

    • 问题2:快速排序法的具体步骤是什么?到底怎么排序?

    • 问题2解决方案:1.先从数列中取出一个数作为基准数。2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。3.再对左右区间重复第二步,直到各区间只有一个数。

    • 问题3:这行代码的意思是什么?作用是什么?

    • 问题3解决方案:java.lang.Character.digit(char ch, int radix)方法,在指定的基数返回字符ch的数值。这行代码是为了确保所获得的这个数是在基数范围内。在书上的代码中,也就是为了确保数字是在0-9之间。

    • 问题4:装填因子是什么?怎么计算?

    • 问题4解决方案:装填因子越大,越不容易产生冲突。装填因子 = 散列表元素个数/哈希表长度

    代码调试中的问题和解决过程

    • 问题1:明明data是泛型数组满足swap方法的形参形式,为什么会红?

    • 问题1解决方案:因为selectionSort方法用的是<T extends Comparable<? super T>>,保持统一swap方法也应该是<T extends Comparable<? super T>>。

    • 问题2:怎么计算程序的执行时间。
    • 问题2解决方案:
    1 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
    2 System.out.println(df.format(new Date()));// new Date()为获取当前系统时间
    
    • Java 获取并计算程序执行时间,有以下两种方法:

    (1)以毫秒为单位计算
    static long currentTimeMillis() , 该方法返回值是从1970年1月1日凌晨到此时刻的毫秒数

    1 long startTime=System.currentTimeMillis();   //获取开始时间
    2 doSomeThing();  //测试的代码段
    3 long endTime=System.currentTimeMillis(); //获取结束时间
    4 System.out.println("程序运行时间: "+(end-start)+"ms");
    

    (2)以纳秒为单位计算

    1 long startTime=System.nanoTime();   //获取开始时间
    2 doSomeThing();  //测试的代码段
    3 long endTime=System.nanoTime(); //获取结束时间
    4 System.out.println("程序运行时间: "+(end-start)+"ns");
    
    • 问题3:列表已经排序好了,为什么还有比较次数?而且次数还不相同?

    • 问题3解决方案:需要进行比较,才能知道是否排序好了,不同的排序方法,需要比较的次数不同。

    • 问题4:PP9.2所写的类形参是T[] data,在测试类中如果直接用int[],是不行的。

    • 问题4解决方案:T[] 是针对对象而言的,所以如果想直接放入数字,那么需要用Integer[]来实现。

    代码托管

    上周考试错题总结

    • 无错题。

    点评过的同学博客和代码

    其他(感悟、思考等,可选)

    • 这周的内容很多并且也比较重要,新的知识较多,花费了大量时间去学习,我觉得这周是开学到至今学的最认真的一周了。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 2/2
    第二周 1010/1010 1/2 10/12
    第三周 651/1661 1/3 13/25
    第四周 2205/3866 1/4 15/40
    第五周 967/4833 2/6 22/62
    • 计划学习时间:30小时

    • 实际学习时间:22小时

    • 改进情况:这周的内容是真的多。而且非常重要,虽然原理简单,但是代码实现起来还是有一定难度的。

    参考资料

  • 相关阅读:
    科研第四天
    科研第三天
    科研的第一天
    django_1.6.8学习笔记——创建project
    第一个project,累哭的第一个app
    前记
    线性表——单链表小结(腾讯面试题)(4)
    一个考试模拟界面——先记录一下下ui上的东东
    源码0602-05-掌握-多值参数
    源码0602-03-掌握-XML解析-NSXMLParser
  • 原文地址:https://www.cnblogs.com/yu757503836/p/9795659.html
Copyright © 2011-2022 走看看