2018-2019-20172309 《程序設計與數據結構(下)》第三週學習總結

教材學習內容總結

教材學習內容總結

5.1 隊列概述

  • 隊列的元素是按照FIFO方式處理的:第一個進入的元素,也就是第一個退出的元素。
  • 隊列的處理方式與棧相反,棧的處理方式是LIFO。
  • 隊列中的方法有enqueue,dequeue,first等同於棧中的push,pop,peek

5.2 java API中的隊列

  • java集合API提供了java.util.Stack類,他實現了棧集合。但他並無提供隊列類,而是提供了一個Queue接口。
  • java.util.Stack類提供了push,pop和peek等操做,queue接口提供了兩個方法add和offer。
  • queue中的方法:

5.3 使用隊列:代碼祕鑰和售票口模擬。

  • 隊列是一種可儲存重複編碼祕鑰的遍歷集合。
  • 一般用表示排隊的隊列來實現模擬。

5.4 隊列ADT

  • 就像棧同樣,咱們也定義一個泛型QueueADT接口,表示隊列的操做,把操做的通常目標與各類實現方式分開。

5.5 實現隊列

5.5.1 用鏈表實現對列

  • 兩個分別指向鏈表首元素、鏈表末元素的引用方便隊列的鏈表實現。
  • 對於單向鏈表,可選擇從末端入列,從前段出列。雙向鏈表能夠解決須要遍歷鏈表的問題,所以在雙向鏈表實現中,無所謂從哪端入列和出列。
  • 代碼:
public class CircularArrayQueue<T> implements QueueADT<T>
{
    private final static int DEFAULT_CAPACITY = 100;
    private int front, rear, count;
    private T[] queue; 
  
    /**
     * Creates an empty queue using the specified capacity.
     * @param initialCapacity the initial size of the circular array queue
     */
    public CircularArrayQueue (int initialCapacity)
    {
        front = rear = count = 0;
        queue = (T[]) (new Object[initialCapacity]);
    }
  
    /**
     * Creates an empty queue using the default capacity.
     */
    public CircularArrayQueue()
    {
        this(DEFAULT_CAPACITY);
    }    
    
    /**
     * Adds the specified element to the rear of this queue, expanding
     * the capacity of the queue array if necessary.
     * @param element the element to add to the rear of the queue
     */
    public void enqueue(T element)
    {
        if (size() == queue.length) 
            expandCapacity();
    
        queue[rear] = element;
        rear = (rear+1) % queue.length;
    
        count++;
    }
    
    /**
     * Creates a new array to store the contents of this queue with
     * twice the capacity of the old one.
     */
    private void expandCapacity()
    {
        T[] larger = (T[]) (new Object[queue.length *2]);
    
        for (int scan = 0; scan < count; scan++)
        {
            larger[scan] = queue[front];
            front = (front + 1) % queue.length;
        }
    
        front = 0;
        rear = count;
        queue = larger;
    }
    
    /**
     * Removes the element at the front of this queue and returns a
     * reference to it. 
     * @return the element removed from the front of the queue
     * @throws EmptyCollectionException  if the queue is empty
     */
    public T dequeue() throws EmptyCollectionException
    {
        if (isEmpty())
            throw new EmptyCollectionException("queue");
    
        T result = queue[front];
        queue[front] = null;
        front = (front+1) % queue.length;
    
        count--;
    
        return result;
    }
  
    /** 
     * Returns a reference to the element at the front of this queue.
     * The element is not removed from the queue.  
     * @return the first element in the queue
     * @throws EmptyCollectionException if the queue is empty
     */
    public T first() throws EmptyCollectionException
    {
        if (isEmpty()){
            throw  new EmptyCollectionException("queue");
        }
        else
            return queue[front];
        // To be completed as a Programming Project
    }
  
    /**
     * Returns true if this queue is empty and false otherwise.
     * @return true if this queue is empty 
     */
    public boolean isEmpty()
    {
       return count==0;
        // To be completed as a Programming Project
    }
  
    /**
     * Returns the number of elements currently in this queue.
     * @return the size of the queue
     */
    public int size()
    {
        return  count;
        // To be completed as a Programming Project
    }
  
    /**
     * Returns a string representation of this queue. 
     * @return the string representation of the queue
     */
    public String toString()
    {
       String result = "";
       int a =front;
       for (int i = 0 ;i< count;i++){
           result += queue[a]+" ";
           a++;
       }
       return  result;
        // To be completed as a Programming Project
    }
}

5.5.2 用數組實現隊列

  • 因爲隊列操做會修改集合的兩端,所以將一段固定於索引0處要求移動元素。
  • 非環形數組實現元素的移位,將產生O(n)的複雜度。
  • 將數組看做是環形的,能夠去除在隊列的數組實現中把元素移位的須要
  • 代碼:
public class LinkedQueue<T> implements QueueADT<T>
{
    private int count;
    private LinearNode<T> head, tail;

    /**
     * Creates an empty queue.
     */
    public LinkedQueue()
    {
        count = 0;
        head = tail = null;
    }

    /**
     * Adds the specified element to the tail of this queue.
     * @param element the element to be added to the tail of the queue
     */
    public void enqueue(T element)
    {
        LinearNode<T> node = new LinearNode<T>(element);

        if (isEmpty())
            head = node;
        else
            tail.setNext(node);

        tail = node;
        count++;
    }

    /**
     * Removes the element at the head of this queue and returns a
     * reference to it. 
     * @return the element at the head of this queue
     * @throws EmptyCollectionException if the queue is empty
     */
    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;
    }
   
    /**
     * Returns a reference to the element at the head of this queue.
     * The element is not removed from the queue.  
     * @return a reference to the first element in this queue
     * @throws EmptyCollectionException if the queue is empty
     */
    public T first() throws EmptyCollectionException
    {
        if (isEmpty()){
            throw  new EmptyCollectionException("queue");
        }
        else
            return head.getElement() ;
        // To be completed as a Programming Project
    }

    /**
     * Returns true if this queue is empty and false otherwise. 
     * @return true if this queue is empty 
     */
    public boolean isEmpty()
    {
        return  count == 0;
        // To be completed as a Programming Project
    }
 
    /**
     * Returns the number of elements currently in this queue.
     * @return the number of elements in the queue
     */
    public int size()
    {
        return count;
        // To be completed as a Programming Project
    }

    /**
     * Returns a string representation of this queue. 
     * @return the string representation of the queue
     */
    public String toString()
    {
        String result = "" ;
        while(head!=null){
            result+=head.getElement()+" ";
            head = head.getNext();
        }
        return  result;
        // To be completed as a Programming Project
    }
}

5.6 雙向鏈表

課後做業:

代碼總覽:

測試結果

  • pp5.1 pp5.2:前端

  • pp5.7:java

教材學習中的問題和解決過程

  • 問題1:課本81頁說:在鏈表的前端實現dequeue操做,需將一個臨時變量指向鏈表前端的元素,而後把front變量設置爲第一個節點的next指針的值。 我想問爲何不能夠直接front.next = front.next.next
  • 問題1解決方案:我的以爲兩種方法均可以。
  • 問題2:如何理解front = (front + 1 ) % queue,length?
  • 問題2解決方案:書上說是非環形的數組實現元素移位,將產生O(n)的複雜度,因此把數組看做是環形的,能夠除去在隊列的數組實現中把原始與移位的須要。

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

  • 問題1:用數組實現鏈表時,使用兩次enqueue方法,在使用一次dequeue方法,發現第一次實現的沒有用爲null。
    node

  • 問題1解決方案:toString方法出現錯誤:
    修改前:
    修改後:
    出現這個問題的緣由是:當使用dequeue方法後不知道front已經發生變化。git

代碼託管

上週考試錯題總結

  • 錯題暫未公佈

點評模板:

  • 隊友值得學習的地方:
    • 課本內容記錄詳細,課本中的有些錯誤也能發現並及時糾正。
    • 不懂得地方選擇本身嘗試,選擇去敲代碼驗證。

點評過的同窗博客和代碼

  • 本週結對學習狀況
    • 20172310
    • 結對學習內容
      • 第五章內容
      • 如何用數組、鏈表實現對列
      • 雙向對列的編程

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

雖然這一章使用的是之前的知識,好比相關的數組、棧、多態、繼承什麼的,可是發現本身仍是不能很熟練的運用。不少基礎概念仍是很模糊,說明本身仍是得加油。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 075/200 1/1 05/20
第二週 560/500 1/2 13/38
第三週 983/1000 1/3 21/60

補充做業

  • (寫以前說一下,以前沒有看到這個補充做業,如今補充)

參考文獻

相關文章
相關標籤/搜索