20182320《程序设计与数据结构》第八周学习总结

教材学习内容总结

1.第十三章:查找与排序

1.1 线性查找

在序列中一个接一个往下遍历查找,找到后退出,一直遍历到最后一个位置说明没找到,退出。

提高效率的查找方法:设置哨兵

从序列的后面往前面查找,设置第一个点为哨兵,并设一个数n记录当前坐标,遍历完序列弹出的条件为"n==0"。

1.2 二分法查找

首先,要将需要查找的序列按大到小或小到大顺序排成新的序列,然后在序列中设置三个指针high、low和middle,high和low一开始指向序列的头和尾,middle=(high+low)/2,然后将要查找的元素和下标为middle的元素相比较:

(1)相等,则查找成功。

(2)大于,则将low赋为middle+1,进行下一轮查找。

(3)小于,则将high赋为middle-1,进行下一轮查找。

这个查找方法会慢慢遍历到序列两端,相比线性查找进行那么多次比较,二分法的效率会更高。

1.3 排序

这一节主要涉及以下排序方法:

选择排序、插入排序、冒泡排序、快速排序、归并排序。前三种效率差不多,而后两者效率更高,也更复杂。

因为对选择和冒泡比较熟悉,所以主要记录一下插入排序、快速排序和归并排序。

1.3.1插入排序

语言解释远没有图片来的直接,上图:

这种插入排序是在逐步的插入中形成有序的序列,但是在编程时会存在插入的困难,因为如果是以数组构建的序列,排好的元素要一个个挪动来给插入的元素让位。如果是以链表构建的序列,插入会比数组相对更方便点。

1.3.2快速排序

图解如下:

这个排序方法的关键在于选取基准点,其中每一轮的交换目的在于找到基准点的正确位置,当我们确立了n-1个点的位置之后,最后一个点的位置也自然就确立了。

1.3.3归并排序

图解如下:


归并的主要思想是将序列拆分成小块,分别进行排序之后再逐步合并排序。而这种方法还可以在着一种情况下得到简化:例如,前面一块是1和3,后面一块是4和8,那么一检测到3小于8,直接不用进行拆分比较,就能得出前面那块小于后面那块,直接合并成下一个整块。

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

问题1:

如何将快速排序用代码实现?

问题1解决方案:

可以使用递归,每次递归代表一趟快速排序

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

问题1:

在https://common.cnblogs.com/editor/tiny_mce/plugins/uploadImage/img/img.gif做pp13.6时,题目提出一个记录程序运行时间的要求,但是我们目前没接触过相关的要求,也完全不知道相关代码。

问题1解决方案:

博客园

问题2:

发现依照上面的第一种做法来计算运行时间得出的结果都是0

问题2解决方案:

因为运行时间太短,上面第一种以毫秒形式计算不出来,所以使用第二种,以纳秒为单位计算。

而且每次的运行时间都不完全一样。

问题3:

想实现数组之间的赋值时,发现:

Integer[] a=new Integer[10]; 

int a[10];

之间好像并不完全相等。

问题3解决:

目前未解决。只知道,前者想赋给作为参数的后者,程序是会报错的。

代码托管

结对及互评

点评过的同学博客和代码

  • 本周结对学习情况
    • 结对学习内容
      • 选择排序
      • 冒泡排序
      • 快速排序
      • 归并排序
  • 上周博客互评情况

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

从这一章的学习中我感受到:
从图文上理解较为复杂的快速排序、归并排序,很容易把握其中的思想,但是把这种理解用代码实现,却涉及更复杂的逻辑,比如涉及递归的思想等。
其次,在代码中加入记录的语句,比如记录比较次数,都需要重新考虑代码的结构和功能,实现的时候比较烧脑,可能会纠结于自己写的这个语句到底是记录了比较的次数还是交换的次数。我觉得除了插入记录,还能有更好的记录方法。

学习进度条

目标10000行30篇400小时
第一周208/2082/29/9
第二周258/4662/415/24
第三周693/11592/622/46
第四周1383/25422/830/76
第五周1300/38422/1022/98
第六周1998/58402/1224/122
第七周2901/87412/1430/152
01-31 19:15
查看更多