zoukankan      html  css  js  c++  java
  • 20172314 2018-2019-1《程序设计与数据结构》第三周学习总结

    教材学习内容总结

    概述

    • 队列是一种线性集合,其元素从一端加入,从另一端删除,所以队列元素是先进先出。

    • enqueue:向队列末端添加一个元素

      dequeue:从队列前端删除一个元素

      first:考察队列前端的那个元素

      isempty:判定队列是否为空

      size:判定队列中的元素数目

      tostring:返回队列的字符串表示

    Java API中的队列

    • Queue接口

      Queue接口并没有实现传统的enqueue,dequeue,和first操作,Queue接口定义了另外两种方法,往队列中添加元素或从队列中删除元素,在异常类处理上,一个提供了布尔返回值,另一个抛出一个异常。

    • Queue接口定义一个element方法,该方法等价于first、front或peek。该方法检索队列首部的元素,但不删除它。

    • Queue接口提供了两个方法add和offer,add操作可以确保队列含有给定的元素,如果给定的元素没有添加到队列将给出一个异常;offer操作把给定元素插入到队列中,插入成功返回true,否则返回false。

    使用队列:代码密钥

    • 凯撒加密法:

      是一种简单的消息编码方式:它根据字母表将消息中的每个字母移动常量的k位。例如,如果k等于3,则在编码后的消息中,每个字母都会向前移动3位:a会被替换成d,b会被替换成e,c会被替换成f,依此类推。字母表末尾将环绕到字母表开头。于是,w会被替换成z,x会被替换成a,y会被替换成b,z会被替换成c。

      解码消息:每个字母会反方向移动同样的位数。因此,如果k等于3,下面这条已编
      码的消息:
      vipsolflwb iroorzv frpsohalwb
      会被解码成
      simplicity follows complexity

    • 重复密钥:

      可以将每个字母移动常数位,而是利用一个密钥值列表,将各个字母移动不同的位数。如果消息比密钥值列表更长,可以从头再次使用这个密钥列表。例如,假设密钥值为317425,那么第1个字母会移动3位,第2个字母会移动1位,第3个字母会移动7位,等等。将第6个字母移动5位之后,会从头再次使用这个密钥列表。于是第7个字母会移位第8个字母会移动1位,等等。

    • 队列是一种可存储重复编码密钥的便利集合。

    • 队列的性质使得密钥值能保持正确的次序:不用担心何时抵达密钥末尾,该如何从头开始。

    使用队列:售票口模拟

    队列ADT

    用链表实现队列

    • 我们必须要操作链表的两端,需要一个指向链表首元素的引用(head),还需要一个指向链表末元素的引用(tail)。这样方便队列的链表实现。

    • 往链表前端添加新结点,就把该新结点的next指针设置成指向链表的head变量,把head变量设置成指向新结点。如果是往链表的末端添加新结点,那就把链表末端结点的next指针设置成指向新结点,然后把链表的tail设置成指向新结点。

    • 对于单向链表,可以选择从末端入列,从前端出列。这样操作的复杂度低;在双向链表中,无所谓从哪端入列和出列。

    • enqueue操作:将新元素放到链表末端。

      public void enqueue(T element) {
          LinearNode<T> node = new LinearNode<T>(element);
      
          if (isEmpty())
              head = node;
          else
              tail.setNext(node);
          tail = node;
          count++;
      }
      
    • dequeue操作:首先要确保至少存在一个可返回元素,并且删除队列前端元素。

      public T dequeue() throws EmptyCollectionException {
          if (isEmpty())
              throw new EmptyCollectionException("queue");
      
          T result = head.getElement();
          head = head.getNext();
          count--;
      
          if ((isEmpty()))
              tail = null;
      
          return result;
          }
      

    用数组实现队列

    • 队列操作会修改集合的两端,因此将一端固定于索引0处要求移动元素。

    • 非环形数组实现的元素移位,将产生O(n)的复杂度。

    • 队列前端固定在索引0处,删除元素时,dequeue操作复杂度为O(n);队列末端固定在索引0处时,元素入列时,enqueue操作的复杂度为O(n)。

    • 把数组看做环形的,可以除去在队列的数组实现中把元素移位的需要。

    • 环形数组:是用数组来存储队列的方法,数组的最后一个索引后面跟的是第一个索引。

    • 使用环形数组,某个元素一旦添加到队列中,它就存储在数组的某个位置,直到用dequeue操作把他删除。


    • 用线性图来理解就是:

    • enqueue操作,其中实现了rear在适当的时候绕回到0.

      public void enqueue(T element) {
          if(size() == queue.length)
              expandCapacity();
      
          queue[rear] = element;
          rear = (rear+1) % queue.length;
      
          count++;
      }
      
    • dequeue操作

      public T dequeue() throws EmptyCollectionException {
          if(isEmpty())
              throw new EmptyCollectionException("queue");
      
          T result = queue[front];
          queue[rear] = null;
          front = (front + 1) % queue.length;
      
          count--;
          return result;
      
      }
      
    • 双端队列:是队列的扩展,它允许从队列的两端添加、删除和查看元素。

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

    • 问题一:为什么单向链表末端入列前端出列更好?

    • 问题一解决:

      (1)在链表末端进行enqueue操作,而在链表前端进行dequeue操作,在进行dequeue操作时,只需要设置一个临时变量指向链表前端的元素,然后把front变量设置为第一个节点的next 指针的值。
      (2)在链表的前端进行enqueue操作,末端进行dequeue操作,那么为了从末端出列,必须把一个临时变量设置为指向链表末端的元素,然后把tail指针设置为指向当前末端之前的结点。在单项链表中必须遍历才能找到该结点,这样复杂度为O(n)
      (3)相比较来说,末端入列前端出列更合适。

    • 问题二:环形数组为什么不需要移位

    • 问题二解决:参考数组实现的 环形队列

      每次出队操作,头指针后移,每次入队,尾指针也后移。因为数组是固定长度连续空间,首位指针后移,队尾可插入区域会越来越小。当然,可以每次出队,整个队列前移,但是数组移动需要牺牲性能。环形队列可以解决数组移动的缺点,当尾指针超出数组末尾时,尾指针移动数组头部。这就将数组虚拟成了一个环形,只要队列长度没达到最大值,就可以插入,而不用移动数组。

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

    • 问题一:在做课堂测试时,需要给出size、isEmpty和toString等方法的定义,以完成LinkedStack类的实现。但是在测试toString方法时,总是显示空指针

    • 问题一解决:开始的toString方法如下

          public String toString(){
            LinnearNode node = new LinnearNode();
            node = top;
            while (node != null) {
                System.out.print(node.getElement()+ " ");
                node = node.getNext();
            }
    
            return node.getElement().toString();
    

    但是由于在while循环之后,node是不断变化的,最后返回的并不是链表内容,修改为如下代码,用字符串形式将链表返回。

        LinnearNode<T> node ;
        String a = "";
        node = top;
    
            while (node != null) {
                a += node.getElement().toString()+ " ";
                node = node.getNext();
            }
            return a;
    

    代码托管

    • PP5-1

    • PP5-2

    • PP5-7

    上周考试错题总结

    • 上周无测试

    结对及互评

    点评模板:

    • 博客中值得学习的或问题:

      • 20172305谭鑫的疑难问题解决的很好,内容全面,排版精美。
      • 20172323王禹涵的博客中课本内容总结有具体代码,但遇到的问题及解决过程的记录可以更加丰富一点。
    • 基于评分标准,我给谭鑫的博客打分:6分。得分情况如下:

      • 问题加分3分
      • 感悟不假大空加1分
      • 排版精美的加1分
        -正确使用Markdown语法加1分
        -模板中的要素齐全加1分
    • 基于评分标准,我给王禹涵的博客打分:6分。得分情况如下:
      • 排版精美的加1分
      • 问题加分2分
      • 感悟不假大空加1分
        -正确使用Markdown语法加1分
        -模板中的要素齐全加1分

    其他

    感觉最近学习的这几章内容是一个套路的,所以有点点混乱。在Java上下的功夫有所减少,要及时温习,熟悉课本。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积)
    目标 5000行 30篇 400小时
    第一周 0/0 1/1 8/8
    第二周 1163/1163 1/2 15/23
    第三周 774/1937 1/3 12/50

    补充作业

    补充作业:在你一生中身体最健康、最旺盛的时候,能在大学学习和研究,是一生中少有的机会。请说明一下,你以及具备的专业知识、技能、能力上还差距哪些?请看这个技能调查表,从表中抽取5-7项你认为对你特别重要的技能,记下你目前的水平,和你想在课程结束后达到的水平(必须列出5项)链接

    技能 课前 课后
    Programming Overall / 对编程整体的理解 3 8
    Programming: Comprehension(程序理解)(如何理解已有的程序,通过阅读,分析,debug) 4 9
    Personal Software Process (个人软件过程):估计,记录工作量,并逐步提高 6 9
    Programming:Implementation(模块实现,逐步细化) 2 9
    Programming:Design (架构设计,模块化设计,接口设计) 1 8

    参考:

  • 相关阅读:
    Linux下安装nginx
    使用Nginx搭建集群
    怎样解决虚拟机中多台机器之间的相互通信问题??
    怎样安装vmtools
    常用的机器学习&数据挖掘知识(点)领域链接
    sparkan安装链接
    matlab中怎样将散点用光滑曲线连接起来??
    matlab中怎样画出散点图,将这些散点连接成线??
    matlab中怎样计算两个集合的差集?-setdiff函数
    MATLAB中在一个三维矩阵中如何提取出一个二维矩阵,使用permute
  • 原文地址:https://www.cnblogs.com/YiYiYi/p/9710336.html
Copyright © 2011-2022 走看看