1. 程式人生 > >20172303 2018-2019-1 《程序設計與數據結構》第3周學習總結

20172303 2018-2019-1 《程序設計與數據結構》第3周學習總結

aci 效率 link 數據 移動 數組 emp logs 雙端隊列

20172303 2018-2019-1 《程序設計與數據結構》第3周學習總結

教材學習內容總結

本周學習了課本第五章的內容,主要介紹了一種新的線性集合——隊列。講解了關於隊列的相關概念以及使用鏈表和數組實現隊列的方法。

一、隊列概述

  • 元素處理方式:先進先出(First In First Out,FIFO),第一個進入的元素也將是第一個退出的元素。
    • 隊頭(front或head):取出數據元素的一端。
    • 隊尾(rear或tail):插入數據元素的一端。
  • 隊列的操作
    • enqueue(也稱add或insert):向隊列末端添加一個元素
    • dequeue(也稱remove或serve):從隊列前端刪除一個元素
    • first(也稱front):考察隊列前端的那個元素
    • isEmpty:判斷隊列是否為空
    • size:判斷隊列中的元素數目
    • toString:返回隊列的字符串表示
  • 應用:存儲重復編碼密鑰、實現售票窗口排隊等
  • 隊列的類型
    • 順序隊列
      技術分享圖片
    • 循環隊列
      技術分享圖片

因為隊列的後四種操作的實現都比較簡單,和之前棧的相關類似操作比較類似。主要的不同體現在enqueue和dequeue上,因為棧只需在集合的一端操作,而隊列需要在兩端實現,所以接下來的內容主要在enqueue和dequeue兩種方法上進行討論。

二、用鏈表實現隊列

  • 用鏈表進行實現時,要設置兩個引用,一個指向鏈表首元素的引用(head),一個指向鏈表末尾元素的引用(tail)。
  • 對於單向鏈表,一般選擇從末端入列,前端出列。雖然不論從前端還是後端入列,其復雜度均為O(1)。但出列時會有很大不同,從鏈表前端刪除時復雜度仍為O(1),但在鏈表末端刪除時,為了尋找到最末端元素的前一個,必須遍歷鏈表,這樣它的復雜度為O(n),就不如從前端刪除的速度快了。
  • 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處。如果是單向列表,在刪除元素時要移動元素,使得操作的效率很低,所以這種情況下可以使用環形數組來實現隊列。
  • enqueue操作
public void enqueue(T element) {
        if (size() == queue.length) {
            expandCapacity();
        }
        queue[rear] = element;
        rear = (rear + 1) % queue.length;//關鍵代碼:用於正確更新rear的值
        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:書上對於雙端隊列只是簡單地講了一下,它的具體操作有哪些?
  • 問題1解決方案:Deque的含義是“double ended queue”,即雙端隊列.Deque是一種具有隊列和棧的性質的數據結構。雙端隊列中的元素可以從兩端彈出,其限定插入和刪除操作在表的兩端進行。Deque在Java中以接口的形式存在,同時Deque還繼承Queue(隊列)的接口。
  • Deque的類圖:
    技術分享圖片
  • 通過類圖可以發現,Deque繼承了Queue(隊列)的接口,它的直接實現有ArrayDeque、LinkedList等。
  • Deque的基本方法
    技術分享圖片
  • 由於Deque接口繼承Queue接口,Deque也可以當做隊列使用。
    技術分享圖片
  • 除此之外,Deque也可以當做棧使用。
    技術分享圖片

代碼調試中的問題和解決過程

  • 問題1:在敲課本上的代碼時發現很多標紅,在改過之後還是不能輸出正確答案。
    技術分享圖片
  • 問題1解決方案:再仔細看了一下發現是代碼中有的變量寫錯了,所有改正部分已在下圖指出。
    技術分享圖片

代碼托管

上周考試錯題總結(正確為綠色,錯誤為紅色)

上周沒有課堂測試。

結對及互評

點評模板:

  • 博客中值得學習的或問題:
    • 優點:相較上周在博客內容方面有所改進,望繼續努力。
    • 問題:博客還是圖文並茂好一些,這樣自己或者別人都看得舒服一些_(:з」∠)_ 對於代碼運行中的問題的整個過程的記錄希望可以更詳細一些。
  • 代碼中值得學習的或問題:
    • 優點:代碼相比我的更加簡潔,命名更加規範。
    • 問題:commit相比上學期寫的不是很好。

      點評過的同學博客和代碼

  • 本周結對學習情況
    • 20172322
    • 結對學習內容
      • 主要討論了藍墨雲的課堂實踐內容,對於用鏈表實現插入和刪除的功能進行了深入地探討。

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

沒想到書上的代碼也會有錯,所以說敲代碼的時候也不能不用腦子地機械敲擊,這樣很容易產生錯誤。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一周 10/10 1/1 10/10
第二周 246/366 2/3 20/30
第三周 246/366 1/4 10/40
  • 計劃學習時間:10小時

  • 實際學習時間:10小時

  • 改進情況:感覺本周的東西相對比較容易,和上周也有許多類似,所以學起來沒有上周那麽困難了。

參考資料

  • java數據結構與算法之(Queue)隊列設計與實現

  • 深入了解雙端隊列Deque

  • Java 集合深入理解(10):Deque 雙端隊列

20172303 2018-2019-1 《程序設計與數據結構》第3周學習總結