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

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

教材学习内容总结

  • 列表:列表集合没有内在的容量大小,它可以随着需要而增大。
    • 有序列表:列表中元素有内在关联,直接定义了元素之间的顺序。
    • 无序列表:元素按着使用者所选择的任意方式排序
    • 索引列表:元素可以用索引来引用。
  • 实现Serializable接口。目的是为了某个对象能使用串行化进行存储。 该接口中没有任何方法,只是表明该对象可以转换为串行化表示形式。
  • Josephus问题是适合用索引列表来求解的计算问题。这类问题着眼于,当列表中的事件不是按顺序取出而是按每隔i个元素提取,直到一个不剩,如何找到这些事件的顺序。
  • 使用数组实现列表:要把列表的一端固定在索引0处,设置一个整数变量rear表示列表中的元素数目,同时表示列表末端的下一个可用位置。
    • remove操作:查找作为参数传递的元素,找到就从列表中将其删除。
    • contains操作:在这种情况下需要n个比较操作。方法平均需要n/2次比较操作,因而该操作的复杂度为O(n)。
    • add操作:有序列表中需要进行n次比较和平移操作,操作的复杂度为O(n)。无序列表中addToFront需要平移n-1个元素,操作复杂度为O(n)。addToRear操作复杂度为O(1)。addAfter需要比较和平移n次,操作复杂度为O(n)
  • 使用链表实现列表:
    • remove操作:链表实现的不需要平移元素来填补空隙。但是在最坏的情况下,需要进行n次比较操作的情况,确定目标不再列表中,因此其时间复杂度也为O(n)。

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

  • 问题1:书P93 链表和列表的具体区别。列表是不是就是线性表。
  • 问题1解决方案:
    • 首先,注意,这里的链表不同于我们所学习的物理结构链式结构,它是一种线性表。
    • 列表则是一种线性表集合,使事物以线性列表的方式进行组织。简单来说,按顺序排好的元素集合就是表。 列表也可以使用链表或数组来进行实现。列表有三种类型:有序列表,无序列表,索引列表。
    • 线性表有两种存储结构:顺式存储结构、链式存储结构。
    • 所以,由此可见,列表对于链表应该是一种包含关系。不确定列表与线性表的关系。
  • 问题2:索引链表和数组的区别是什么?不应该是容量么?书上P95 的坍塌是应该如何理解。
  • 问题2解决方案:
    • 书上给出索引列表的概念

      索引列表为它的元素维护一段连续的数字索引值。

      然后书上说

      索引列表和数组的根本区别在于:索引列表的索引值总是连续的。

    • 先不说这句话如何理解,但是我觉得索引列表和数组的根本区别就是容量。数组申请空间之后大小就固定了。而列表的空间容量是可以动态增长的。
      而因为数组的容量是固定的,所以导致使用数组的时候造成空间的浪费。当你增加元素达到数组填满了的时候,如果不开辟新的空间,则无法继续增加元素。所以数组该设置多大是一个需要解决的问题,但有时候你无法确定到底需要多大的数组来存储一个大小在变化的表。解决的其中一个办法是当发现数组满,申请一个新的更大的数组,然后将元素全部移至新的数组。但怎么处理掉原数组也是一个问题。
      所以这时候,才会有列表的出现。

    • 而书上所指的 “坍塌”,根本指的是使用数组解决问题是增加删除元素的效率。 插入或删除某个元素,则其对应位置后的所有元素均需移动。这所需要的时间复杂度会增加。

  • 问题3:Serializable接口的作用。书中已经说了,类实现了Serializable接口,就能使对象串行化进行存储。那么,这个串行化是什么表现形式。
  • 问题3解决方案:
    • 其实串行化应该是序列化 。Serializable接口是类可以被序列化的特性,表示这个类可以被序列化。
    • 什么叫序列化?我们都知道对象是暂时保存在内存中的,不能用U盘考走了,有时为了使用介质转移对象,并且把对象的状态保持下来,就需要把对象保存下来,这个过程就叫做序列化 ,通俗点,就是把人的魂(对象)收伏成一个石子(可传输的介质)
    • 什么叫反序列化?就是再把介质中的东西还原成对象,把石子还原成人的过程。
    • 在进行这些操作的时候都需要这个可以被序列化,要能被序列化,就得给类头加Serializable接口。通常网络程序为了传输安全才这么做。

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

  • 问题1:书P103 代码中的instanceof的意义和具体用法

  • 问题1解决方案:

    • 首先,根据上下文的理解,先给出我的一个初见。应该是判断两个对象类型是否一样的一种方法

    • 然后,查询API发现并没有这个方法。之后我便理解了。因为,instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字。 它不是一个方法或类,就没有体现在API中。

    • 它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据。用它来判断某个对象是否是某个Class类的实例。

    • 注意:null值不是任何对象的实例, 所以下面这个例子返回了false,无论这个变量声明的是什么类型。

    String s = null;   
    if ( s instanceof String )   
    
    • instanceof也可以正确的报告一个对象是否是数组和特定的接口类型。
    if ( foo instanceof byte[] )
    
  • 问题2:用链表实现有序列表添加操作时候的空指针异常。

  • 问题2解决方案:

    • 在列表的链表实现中,最常见和最普遍的错误就是空指针异常。需要我们在相应错误的地方进行调试,观察调试过程,从而发现何时指针为空。
     public void add(T element) {
        if (!(element instanceof Comparable))
            throw new NonComparableElementException("OrderedList");
    
        Comparable<T> comparableElement = (Comparable<T>)element;
    
        LinearNode<T> current = head;
        LinearNode<T> previous = null;
        LinearNode<T> node = new LinearNode<>(element);
    
    
        while (( current != null) && (comparableElement.compareTo(current.getElement()) > 0))
        {
            previous = current;
            current = current.getNext();
        }
    
        if (previous == null )
        {
            head = node;
        }
        else {
            previous.setNext(node);
        }
    
        node.setNext(current);
    
        count++;
        modCount++;
    }
    
    • 这是我有序列表的插入代码,在运行调试之后,他的报错位置在这里。
        while ( comparableElement.compareTo(current.getElement()) > 0 && current != null )
    
    • 这是我一开始的错误代码。我发现,在他进行while判断的时候,是先进行compareTo的比较大小操作,而非判断current是否为空。所以,当current为空的时候,他便直接出现了空指针异常。
    • 所以我们只需要把两个条件相互颠倒一下即可。
       while (( current != null) && (comparableElement.compareTo(current.getElement()) > 0))
    
  • 问题3:用链表实现列表的删除最后一个的时候,出现了空指针异常。

  • 问题3解决方案:

    • 这是我的错误代码。
    public T removeLast() {
        LinearNode<T> previous = null;
        LinearNode<T> current = head;
    
        if(isEmpty())
        {
            throw new EmptyCollectionException("LinkedList");
        }
        while (current != null)
        {
            previous = current;
            current = current.getNext();
        }
        if (size() == 1)
            head = tail = null;
        else {
            tail = previous;
            tail.setNext(null);
        }
        count--;
        modCount++;
    
        return current.getElement();
    }
    
    • 我注意到了,我判断循环条件是current是否空,也就是current为空的时候会跳出循环,那么最后return返回的结果current.getElement肯定抛出空指针异常。
    • 我们只需要把循环条件改成current.getNext() != null 即可。
    • 测试结果截图:

代码托管

上周考试错题总结

第三四章

  • 错题1:Inherited variables and methods can be used in the derived class as if they had been declared locally.
    A .true
    B .false
  • 错因:我认为父类的变量如果声明成private,那么子类是不可以直接调用的。所以我觉得是错的。
  • Common features should be located as low in a class hierarchy as is reasonable, minimizing maintenance efforts.
    A .true
    B .false
  • 错因:公共变量为了方便调用,应该声明在最高的层次。

第五章

  • The first operation removes an element at the front of the queue and returns a reference to it.
    A .True
    B .False
  • 错因:这题我翻译错了,应该是first操作,我看成第一个操作了。尴尬。

结对及互评

点评过的同学博客和代码

  • 上周博客互评情况
    • 20172304
    • 段志轩同学的博客教材知识总结越来越详细具体,说明对教材逐渐有了很深的了解。但是希望他在测试的时候能够更加严谨。尽量的结合教材,加以运用。
    • 20172328
    • 博客写的很具体,但是较之前而言,字里行间有些许浮躁。可能还没有平息假期的激动。教材学习总结的==,是想要高亮么,还是单纯的分隔符。在博客园的markdown格式下==似乎没有任何效果,对应的应该是</mark>

其他

  • 十一的假期让我们可能有些许懈怠,不过磨刀不误砍柴工。适当的放松可以更好地学习。有人,说我的教材知识总结比较少。每个人对于教材的看法不同,教材更多的是一些概念性的问题和代码问题。我一般是只记录了一些我所认为的难点,比如时间复杂度的判断,比如Josephus问题的适用范围。而我个人,更倾向于一些教材中问题的解答,这样能是我的学习更加深刻。一篇好的博客,应该是有灵魂,有血性的博客。有自己的思想和自己所要表达的东西。而不仅仅是简单的截图和代码的陈列。博客更是一种总结,一种自省。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 10/10
第二周 610/610 1/2 20/30
第三周 593/1230 1/3 18/48
第四周 2011/3241 2/5 30/78

参考资料

posted @ 2018-10-07 22:37  奈何明月ઇଓ  阅读(86)  评论(2编辑  收藏
页尾