1 2 3 4

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

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

一、教材学习内容总结(排序与查找)

查找

  • 特点:

1.要么找到它、要么确认他不存在
2.为使查找算法高效,我们应尽可能使比较次数最少化

  • 线性查找法:一个接下一个找,要么找到,要么确认没有要找的元素。空间复杂度为:O(n)
  • 二分查找法:

进行二分查找的数组必须是已经经过排序的。

它会从中间开始找,然后又会从两边的中间找,直至找到,或确认没有该元素。

二分查找每次都会删除一半的可行候选项。空间复杂度为nlog2 n

  • 两种查找的比较:
选项 线性查找 二分查找
空间复杂度 O(n) nlog2 (n)
特点 简单,编程与调试容易,但效率低 效率高,不浪费资源但数组需经过排序

排序

  • 排序的方法有:选择排序、插入排序、冒泡排序、快速排序、归并排序和基数排序法。其中前三个已经学过,不在赘述,主要讲解写后面三个:

    • 快速排序法:
    1. 在列表中选择一个元素作为“点”,名为“基准”。
    2. 将小于该基准的元素放到左边,大于的放到右边。
    3. 递归的将基准两边的子列表进行快速排序(重复步骤一。)
    4. 直至每一个子列表都只含有一个元素的时候结束。
    • 举个例子:

    • 归并排序法:

    1. 首先将列表分成两个达到约相等的子列表。
    2. 然后对每一个子列表递归调用本身,至每个子列表只含有一个元素。
    3. 然后将这些子列表归并到一个排序顺序中。、
    • 举个例子:这张图应该能很好说明这个问题!
    • 基数排序法:见下面问题。
  • 各种排序方法时间复杂度的比较:

    • O(n^2):选择排序、插入排序、冒泡排序。
    • O(nlog2 n):快速排序、归并排序。
    • 基数排序法的时间复杂度为O(d(n+r)),其中,d为位数,r为基数。
  • 代码文件地址

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

  • 问题1:线性查找算法怎么优化?
  • 问题1解决方案:
    原代码:
 while (!found && index <= max) //每一次index都得与max进行比较。
        {
            found = data[index].equals(target);
            index++;
        }

上述算法中,每一次循环index都得max进行一次比较,当max趋于无穷大时,就会很拖延时间。因此我们得尽可能的减少比较的次数,但是如何解决他呢?
我们可以让数组的最后一个元素为target(目标),那么这样肯定会找到,只需找到时返回index,如果index=max+1;那么就是咋们添加的元素,即没找到!

  • 问题2:什么是基数排序方法,如何理解?
  • 问题2解决方法:
    • 直接举个例子吧
    1. 比较个位数字,分别将它们放到对应号码的桶里。然后分别取出来(从桶底取出来)。
    2. 比较十位数字,分别将它们放到对应号码的桶里。然后分别取出来(从桶底取出来)。
    3. 比较百位数字,分别将它们放到对应号码的桶里。然后分别取出来(从桶底取出来)。
    • 一开始的是后还是想不到为什么最后结果为啥就排好了序,仔细一想是这样:
    1. 百分位越大的就大。(第三次排序)
    2. 百分位相同的,十分位大的大。(第二次排序)
    3. 十分位相同的,个位大的大。(第一次排序)
  • 问题三:书中基数排序法用到了队列,咋们以前还学过列表,他们有何异同点?
  • 问题三解决方法:
    • 队列:队列可以用一个循环的数组表示,大小为MAX;有头和尾两个标记head与rear,rear=(rear+1)%MAX;遵循先进先出FIFO原则;
    • 列表:列表是有方向的,由一个个节点组成,每个节点除了包含的元素外,还有只想下一个节点的指针。

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

  • 问题1:如何调用形参中有泛型的方法?我出现了这么个鬼:

  • 问题1解决方案:上面说int[] 不是 T[],这是因为基本数据类型的数组类型不是T[]的子类.
    而应该这样调用:

Integer a[]={5,3,6,8,7,2,1,9,4};
        gapSort(a,1);
  • 问题2:在做pp9.2项目的间隔排序法时(gap sort),需选择一个大于1的整数i作为间隔进行冒泡排序。当完成一轮迭代时,让i--。直到i=0;
    但仔细一想:前面的排序都是没有用的,只有最后一次才是真正的有意义的,所以我就怀疑出题者的意图

  • 问题3:如何计算程序的运行时间?

  • 问题三解决方案:

    • 最初想这个问题是想写一个方法用于计算一个方法的运行时间,传入的参数是一个方法。之后上网查了一下,说是一个方法不能作为形式参数传进另一个方法的。
    • 所以还是要用其他方法,因此我选择让每个方法都返回一个String类型的返回值。例如: return "此方法为insertSort()! "+"比较次数为:"+count+"运行时间为"+(endTime-startTime)+" 纳秒";
    • 其中计算时间的代码是:
      1. long startTime = System.nanoTime();//获取开始的时间;
      2. long endTime = System.nanoTime();//获取结束的时间

课后作业运行截图:

代码托管

上周考试错题总结

  • 上周无错题。

点评模板:

本周结对学习情况

- [20172310]( http://www.cnblogs.com/Qiuxia2017/)
- 结对学习内容
    - 对链表类的测试
    - 对第九章的查找与排序的学习。

上周博客互评情况

- [20172310](https://www.cnblogs.com/Qiuxia2017/p/9781103.html)
- [20172301](https://www.cnblogs.com/hzy0628/p/9786586.html)
  • ...

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

  • 这一章中,主要讲了查找与排序,查找有线性查找与二分查找。其中二分查找是属于新学的方法,但思想以前有了解过。排序前三个排序方法已经学过,后面两个是属于新学的,个人感觉比较难。但最后还是理解了。通过分析这五个排序的时间复杂度,发现好的算法能够大大地提高效率。因此,设计出一个好的算法是非常重要的。

学习进度条(上学期截止7200)

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 260/0 1/1 05/05
第二周 300/560 1/2 13/18
第三周 212/772 1/4 21/39
第四周 330/1112 2/7 21/60
第五周 1321/2433 1/8 30/90

参考资料

posted @ 2018-10-16 23:36  大大的梦  阅读(240)  评论(1编辑  收藏  举报