2018-2019 1《程序设计与数据结构》第五周学习总结

时间:2022-10-12 19:20:47

学号 20172326 《程序设计与数据结构》第五周学习总结

教材学习内容总结

查找算法的总结

  • 线性查找,通过依次遍历所要查找元素的集合,比较是否存在所需查找的元素,直到找到该元素或返回false表明集合不存在该元素。实现较为简单,==但当集合元素数量巨大时,效率极慢==。
  • 二分法查找,通过每次将集合分为两部分,比较所需查找的元素位于中间元素的左半区还是右半区,依次进行二分,直至找到元素,或返回false。效率较高,例如,一个含义一百万元素的集合,只需20次左右即可完成查找。==但二分法的实现需要基于一个有序数组,否则无法实现。==

排序算法的总结

  • 顺序排序——选择排序法,选择排序法每遍历列表依次,找到当前最小元素,将其与列表左侧元素交换,最终将所有元素进行排序。
  • 顺序排序——插入排序法,从最左侧元素开始,与其余元素比较,产生一个初步的排序子集,每当下一个比较的元素小于排序子集的最右元素时,经过与子集元素比较,将其插入到子集的顺序位置。子集不断向右与剩余元素进行比较,直至完成排序。
  • 顺序排序——冒泡排序,将列表中的元素,从左端开始,两个元素比较大小,若左大右小,两个交换位置,一直往复,将最大元素置于最右位置。每次排序都将当前最大的交换到最右
  • 快速排序,使用递归的思想。以一个元素为界限,小在左,大在右。然后在进行递归,左右继续刚才的流程。直到完成排序。其思想与查找中的二分法类似,每次分为两部分,进行排序。从而提高效率。

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

  • 问题1:本章的排序与查找方法大多是由递归实现的,如果使用循环,会有怎样的效果呢?
  • 问题1理解:先来看看递归的定义:递归利用一个方法调用自身来满足其整个作用。也就是说,“我”用“我自己”。每次调用自己的函数,但是,回顾递归的知识,每递归一次,函数调用一次自身,除保存现有的变量以为,还要产生新的变量,新的存储空间。一旦数目较大,递归将占用大量的资源。以二分法为例,如果不使用递归,而是简单的使用多层循环来实现,每执行一次循环,除确定第一位置,最后位置、以及中间位置的值外,不必保存上次寻找是确定的数据。但递归不同,递归将第一次至最后一次的数据全部保留。为了比较二者进行查找的速度,我将两个算法同时查找同一个数组的同一个数字,分别返回二者的时间,结果证明,递归的时间更长。但是,可以发现,递归的代码更加简洁,只需重复的调用自身即可。
    2018-2019 1《程序设计与数据结构》第五周学习总结
    2018-2019 1《程序设计与数据结构》第五周学习总结
  • 从图中可以清晰的看出两者时间的对比,下面为循环实现所耗费的时间,在位数上比使用递归少了一位,而这只是十几个数组的比较,可以想见,如果数字数量巨大,使用递归将占用大量时间,同时,对内存也将造成极大占用

  • 问题2:

<T extends Comparable<? super T>>

中关于 ==?super T== 的理解

  • 问题2理解:一开始对于这个“?”,我认为是“非”的意思,但转念一想,非的符号是!,并且在确定方法的数据类型时,何谈一种非某种数据的数据类型。查阅资料后,得到了答案,?为通配符,除了<? super T>外还有<? extends T>两种。其中前者表示,可以添加父类以及该父类子类的参数,不能添加其超类。同时,其不能返回其相应数据类型的值,只能返回object对象。而<?extends T>表示,类型的上界,表示参数化类型的可能是T 或是 T的子类。
    首先,<T extends Comparable >表示泛型参数应用于该方法,但是,泛型方法并不意味着返回一个泛型数据,而是经过编译器判断后,返回一个具体的数据类型的数据。结合起来,整体意识就为,该方法适用于继承了Comparable借口的T方法,其中该参数继承了泛型类型,但其具体数据类型不明。

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

  • 问题1:pp9-3问题
  • 问题1解决方案:pp9-3要求,将各个排序方法的排序时间进行打印,同时,进行对各方法的排序次数进行计数。排序时间使用
System.nanoTime()

即可得出时间。count也将为简单,但是,在对归并法进行统计时出现了问题。归并法使用了递归的思想,所以,当在递归方法中进行cout++操作以及System.out.println("the count is :")时,会使每次递归都会打印。导致出现

the count is :1
the count is :2
the count is 3
the count is :4
the count is :5

的情况,那么能否将count值进行返回呢?显然是不行的,因为方法均为void型。那么索性将void改为int型,然后将其返回,我们来看一下归并排序的三个方法

public static <T extends Comparable<T>>void mergeSort(T[] data){}
private static <T extends Comparable<T>> void mergeSort(T[] data, int min, int max) {}
private static <T extends Comparable<T>> void merge(T[] data, int first, int mid, int last) {}

这里只截取了三个方法的方法头,可以看到,纵使将三个方法改为有返回值型,一个方法与一个方法之间也无法调用该参数。因为静态方法无法使用非静态参数,除非再将其改为非静态方法。如此一来,仅仅加一个count计数就将带来巨大的变化,实非上策。那么该如何实现呢?其实也很简单。我们要在静态方法里进行操作,那么,就不妨在类头添加一个静态变量,初始化为0,而后,一次交换位置,count++,统计时在第一个方法里直接调用该变量即可。

代码托管

上周考试错题总结

  • 错题1:The elements of an _____________ have an inherent relationship defining their order.
  • 理解:有序列表可以继承元素之间的顺序,这是因为,有序列表的添加方法中已有排序的方法
  • 错题2:The elements of an ordered list do not have an inherent relationship defining their order.
  • 理解:与上一题类似,有序列表即有序线性表在添加元素时就可规定其顺序
  • 错题3:Interfaces cannot be derived from other interfaces.
  • 理解:Java中不允许一个子类继承多个父类,但可以通过实现多个接口来实现类似的形式。
  • 错题4:Interfaces allow us to make polymorphic references, in which the method that is invoked is based on the type of the reference variable rather than the particular object being referenced at the time.
  • 理解:多态性中有这样一句话: 实际调用的方法版本取决于对象的类型而不是引用变量的类型。

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

  • 本周投入了较多的时间用于学习不同排序以及查找方法、算法的学习上,对于某些方法,也进行了一定的研究,今后会继续认真学习

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 3/3
    第二周 409/409 1/2 5/8
    第三周 1174/1583 1/3 10/18
    第四周 1843/3426 2/5 10/28
    第五周 539/3965 2/7 20/48

结对及互评

  • 博客中值得学习的或问题:
    排版精美,对于问题研究得很细致,解答也很周全。
  • 代码中值得学习的或问题:
    代码写的很规范,思路很清晰,继续加油!

点评过的同学博客和代码

  • 本周结对学习情况
  • 20172313
  • 20172332

    结对学习内容

  • 第九章 查找与排序

参考资料

图解排序算法(四)之归并排序
递归和非递归两种方式实现二分法查找