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

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

教材学习内容总结

本周学习了第六章排序与查找php


一些概念

  • 静态方法能够经过类名来激活,不用特地实例化该类的一个对象调用该静态类的方法。在方法声明中,经过使用static修饰符就能够把它声明为静态的
  • 建立泛型方法,只需在方法头前的返回类型前插入一个泛型声明便可。泛型声明必须在返回类型以前,这样泛型才可做为返回类型的一部分
public static <T extends Comparable<T>> boolean
  linearSearch (T[] data, int min, int max, T target)

查找

  • 在某个项目组中寻找某一指定目标元素,或肯定该指定目标不存在,是为查找。进行查找的项目组被称为查找池
  • 线性查找法:从头开始依次比较每个值,直到找到目标元素,或者得出不存在该目标值的结论,这种方式称为线性查找(linear search)
  • 二分查找(折半查找):当查找池中的项目组是已排序的,那么利用二分查找将会更有效率。
    • 二分查找的思路: 二分查找从排序列表的中间开始查找,若是中间元素不是目标元素,根据两个元素的大小关系,再判断从列表的前一半或是后通常进行查找。每次的查找都是从当前一串数字的中间元素开始的。直到最后找到该元素或是没有找到抛出一个信息。
    • 二分查找的每次比较都会删除一半的可行候选项,当查找池中有偶数个待查找值时,选择的是两个中间值的第一个。
    • 二分查找的复杂度是对数级的,这使得它对于大型查找池很是有效率。线性查找具备线性时间复杂度O(n),二分查找具备时间复杂度O(log2n)。

排序

  • 基于某一标准,将某一项目组按照某个规定排序排列
  • 选择排序法
    • 反复寻找当前列表的最小值,而后将其放在列表的前端。
  • 插入排序法
    • 将数字插入前端已排序的列表的合适位置直至排序完成。
  • 冒泡排序法
    • 反复比较相邻元素的大小关系进行移位操做直至排序完成
  • 快速排序法
    • 选择一个列表元素进行分区元素,而后对两个分区进行递归排序直至排序完成(一个分区只含有一个元素2)。
    • 排序时两个分区同时进行查找,一旦两边都找到一个元素,将二者进行互换
  • 归并排序法
    • 将列表递归式分红两半直至每一子列表都含有一个元素,而后再归并到一个排序顺序中完成排序
  • 基数排序法
    • 基数排序基于队列处理

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

  • 问题1:选择排序的代码实现中出现了public static <T extends Comparable<? super T>> void selectionSort (T[] data)之中<? super T>表示的是什么意思
  • 问题1解决方案:查阅资料在网上找到了一个通俗易懂的回答,大体上把<? super T>三个部分都讲得比较清楚了。按照个人理解,在这里?表明的是通配符,这一整串表明的是一个下界通配符,用在此处表明Comparable接口中的泛型元素都是T或者T的父类,这样就放松了存入数组的类型限制,可是引发的缺点就是往外读取元素就会变得困难,可能使元素类型信息丢失。

  • 问题2:几种排序方法时间复杂度的比较
  • 问题2解决方案
排序方法 时间复杂度
选择排序 O(n^2)
插入排序 O(n^2)
冒泡排序 O(n^2)
快速排序 O(n*log2n)
归并排序 O(nlog2n)
基数排序 O(n)

三种顺序排序方法都使用了内外两层循环进行排序操做,因此时间复杂度都为nxn-->O(n^2);
快速排序和归并排序两种对数排序在排序中采起了递归的方法,所以在元素比较中只用到了大约nlog2n次比较,时间复杂度为O(log2n);还有一种特殊的基数排序,由于在排序过程当中不涉及到元素之间的比较,只须要将元素在队列之间进行移动操做,操做时只用遍历数据便可,所以能够用c*n来表示(c是常数),因此时间复杂度为O(n)。html

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

  • 问题1:PP9.2中间隔排序的思路有些混乱,为何每次迭代完成以后i要减小某个大于1的数量直至i的值小于1.
  • 问题1解决方案:在网上没能找到关于间隔排序的资料,因此不太懂原理,应该也和冒泡排序差不太多吧,就按照题目的要求拼好了代码,可运行出来的结果排序彷佛并无完成。前端

    假设如今有一个长度为6的数组,第一次的i为3,每一次迭代后i减小的值为2,那么在第一次迭代中,第一个元素与第三个元素进行比较,第二个元素与第四个元素进行比较,第三个元素与第五个元素进行比较,第四个元素与第六个元素进行比较,第一次迭代结束,i的值为1,第一个元素与第二个元素进行比较...相邻元素分别进行比较,迭代结束,i的值为-1小于1,此时循环结束,排序完成。
    git

若是每次i的值减小1
web

与题目给的信息偏偏想反,反却是每次减一时能得出正确的排序,屡次修改代码中的间隔值,发现i每次减一时排序都能正确完成可是减2、减三时只能是在部分间隔值的状况下才能排序完成数组


  • 问题2:PP9.3如何用代码实现总的比较次数和总执行时间的计数
  • 问题2解决方案
    计时
    最开始应用的代码以下
Date da = new Date();
long s1 = da.getTime();
...//具体运行的代码
long s2 = System.currentTimeMills();
System.out.println(s2 - s1);

代码开始运行时记录当前时间,代码结束前再记录一下当前时间,最后s2-s1即为运行时间,思路是没有问题,但是运行结果出来就有点小瑕疵,如图
数据结构

运行时间全为0且没带单位,我以为系统并无错,可能真是运行时间过短吧,小于一秒的计算机就自动四舍五入归为0了(?),我是这样认为的,因此我又寻找到另外一种比较精密计量时间的方法
以毫秒为单位计算的学习

long startTime = System.currentTimeMillis();//获取当前时间
doSomeThing();
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:"+(endTime-startTime)+"ms");

以纳秒为单位计算的this

long startTime = System.nanoTime();//获取当前时间
doSomeThing();
long endTime = System.nanoTime();
System.out.println("程序运行时间: "+(end-start)+"ns");

好似万事俱备,运行一下试试,问题仍是出现了,毫秒计时依然为0额。
此时我又找到了Date.getTime的说明
Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object
,显然这个方法一样是以毫秒为单位来计量代码运行的时间的,以前什么四舍五入的解释就有问题了,在网上寻找答案也只获得一些绝不沾边的东西,有点束手无策,后来我再仔细一瞅,发现纳秒计时的方法彷佛没有出错啊,因而改为纳秒计时,而后就运行成功???有点莫名其妙。
debug

原觉得计时在稀里糊涂之中就能够所有解决了,把五大排序法中分别加上s一、s2,而后运行一下,此次又是归并排序的计时出现了些问题,如图

debug一下,错误应该出在忽略了递归上面,就是计算机每执行一次mergeSort的方法,就得从新开始计时一次,因此最后的结果会输出不少个归并排序的计时,参照快速排序的方法,至关于在归并排序的外面加一层壳专门用来计时,其余也想不出更好的办法了,最终结果如图


比较次数

  • 对于选择排序、插入排序和冒泡排序,其内层循环都为比较相邻两元素的大小,外层控制存储的位置,因此只需在内层写入一个计数的变量count,每执行一次内层循环count+1.
  • 对于快速排序和归并排序,只要进行了一次compareTo操做count就须要加一,不管是否知足while循环的条件,所以while循环内外都应该有语句count++。

代码托管

上周考试错题总结

上周没有错题哦

结对及互评

  • 博客中值得学习的或问题:
    • 谭鑫的博客一直保持很高的水准,特别是问题的总结和解决能力都值得学习,能看出来是在用心学习
    • 方艺雯的博客教材学习内容总结认真详细,并配有图示和本身的理解,点个赞
  • 基于评分标准,我给谭鑫的博客打分:8分。得分状况以下:
    正确使用Markdown语法(加1分):
    模板中的要素齐全(加1分)
    教材学习中的问题和解决过程, 三个问题加3分
    代码调试中的问题和解决过程, 三个问题加3分

  • 基于评分标准,我给方艺雯的博客打分:8分。得分状况以下:、
    正确使用Markdown语法(加1分):
    模板中的要素齐全(加1分)
    教材学习中的问题和解决过程, 两个问题加2分
    代码调试中的问题和解决过程, 三个问题加3分
    排版精美加1分

  • 本周结对学习状况
    • 20172305
    • 20172314
    • 结对学习内容
      • 排序与查找
      • PP9.4中的比较次数通过反复讨论获得了比较一致的答案
  • 上周博客互评状况

其余

这周在代码学习上仍是遇到了一些小的问题,在资料缺少的状况下,本身动手写代码的能力、分析问题的能力有了一些增强,但仍是稍显欠缺,须要继续努力

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 8/8
第二周 470/470 1/2 12/20
第三周 685/1155 2/4 10/30
第四周 2499/3654 2/6 12/42
第六周 1218/4872 2/8 10/52

参考资料

相关文章
相关标签/搜索