20172314 2018-2019-1《程序設計與數據結構》第三週學習總結

教材學習內容總結

概述

  • 隊列是一種線性集合,其元素從一端加入,從另外一端刪除,因此隊列元素是先進先出。
  • enqueue:向隊列末端添加一個元素html

    dequeue:從隊列前端刪除一個元素前端

    first:考察隊列前端的那個元素java

    isempty:斷定隊列是否爲空node

    size:斷定隊列中的元素數目git

    tostring:返回隊列的字符串表示編程

Java API中的隊列

  • Queue接口api

    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

參考:

相關文章
相關標籤/搜索