Java實現帶頭節點的雙向循環隊列(鏈表)

Deque

●queue 是一種數據結構,該數據結構允許在隊頭添加節點,然後在隊尾刪除一個項,以實現先進先出(FIFO)。

●在這個實驗中,我們將創建一個更通用的數據結構,稱爲 deque,是雙端隊列的縮寫。

●在一個 deque 中,您可以添加和刪除兩端的項(無論是其前端還是後端)。

○在本實驗室,您將完成包括添加和刪除在內的許多方法。

●此外,您必須使用通用類型,以便可以實例化 deque 來存儲任何類型的對象。

我們將使用鏈表實現一個 deque,特別是循環鏈表。

1. LLDeque EMPTY CONSTRUCTOR

●完成空的 deque 構造函數 public LLDeque()

●它創造了一個空的 deque

2. LLDeque ADD TO FRONT

●完成方法 void addFirst(T item)。

●它將一個 T 型 item 添加到 deque 的前部。

●不得使用任何循環或遞歸。

●每次操作必須持續時間,即不取決於 deque 的 size。

提示:

●我們需要創建一個新節點,並將其立即放置在哨兵旁邊

使用輸入項創建一個新節點,其上一個點指向哨兵,下一個點指向哨兵之後的舊節點

●設置哨兵後舊節點的 prev 指向新節點

●設置下一個哨兵指向新節點

●增大 size

3. LLDeque PRINT ITEMS

●完成方法 void printDeque()

●它將 deque 中的項目從頭到尾 print 出來,用空格隔開,以新行結束。

提示:

●我們需要檢查每一項並 print 出來

●項目從哨兵旁邊開始,因此設置一個指針 p 指向它

●當 p 不返回哨兵時 ○使用 Print(非 println)print p 所指節點內的 item ○添加 spacebar ○移動 p 以指向下一個節點

●使用 println 添加新行

4. LLDeque ITERATIVE GET ITEM

●迭代完成方法 T iterGet(int index)。

●它返回給定索引處的項,其中索引 0 是前端。如果不存在此類項,則返回 null。

●它必須使用循環,而不是遞歸。

●不得使 deque 突變。

提示:

●如果 deque 爲空,或者索引無效(負數、大於或等於),則返回 null

●創建一個從哨兵的下一個開始的節點指針 p

●使用 for/while 移動指向 index-th 節點的指針

●返回 p 所指節點內的 item

5. LLDeque ADD TO BACK

●完成方法 void addLast(T item)。

●它在 deque 後面添加了一個 T 類型的 item。

●它不能使用任何循環或遞歸。

●每次操作必須持續時間,即不取決於 deque 的大小。

6. LLDeque DELETE FRONT

●完成方法 T delFirst()。

●刪除並返回 deque 前面的項,如果不存在,則返回空。

●不得使用任何循環或遞歸。

●每次操作必須持續一段時間,即不取決於 deque 的大小。

7. LLDeque DELETE BACK

●完成方法 T delLast()。

●刪除並返回 deque 後面的項,如果不存在,則返回空。

●不得使用任何循環或遞歸。

●每次操作必須持續時間,即不取決於 deque 的大小。

8. LLDeque RECURSIVE GET ITEM

●遞歸地完成方法 T recGet(int index)。

●它返回給定索引處的項,其中索引 0 是前端。如果不存在此類項,則返回 null。

●不得使用循環。

●不得使 deque 突變。

上代碼:

public class LLDeque<T> {

    private class Node {
        Node prev;
        T item;
        Node next;

        Node(Node p, T i, Node n) {
            prev = p;
            item = i;
            next = n;
        }
    }

    private Node sentinel;
    private int size;

    /**
     * @return the number of items in the deque.
     */
    public int size() {
        return size;
    }

    /**
     * @return true if deque is empty, false otherwise.
     */
    public boolean isEmpty() {
        return size == 0;
    }

    /*
     ***************************
     * DO NOT MODIFY CODE ABOVE
     ***************************
     */


    // EXERCISE 8.1 EMPTY CONSTRUCTOR

    /**
     * Creates an empty deque.
     */
    public LLDeque() {
		this.size = 0;
		Node head = new Node(null, null, null);
		head.prev = head;
		head.next = head;
		this.sentinel = head.next;
    }


    // EXERCISE 8.2 ADD TO FRONT

    /**
     * Adds an item of type T to the front of the deque.
     * @param item is a type T object added to the deque.
     */
    public void addFirst(T item) {
		Node newNode = new Node(null, item, null);
		newNode.prev = this.sentinel;
		newNode.next = this.sentinel.next;
		this.sentinel.prev = newNode.next;
		this.sentinel.next = newNode;
		this.size += 1;
    }


    // EXERCISE 8.3 PRINT ITEMS

    /**
     * Prints the items in the deque from first to last,
     * separated by a space, ended with a new line.
     */
    public void printDeque() {
		Node p = this.sentinel.next;
		while(p!=this.sentinel) {
			System.out.print(p.item);
			if(p.next!=this.sentinel) System.out.print(" ");
			p = p.next;
		}
		System.out.print("\n");
    }


    // EXERCISE 8.4 ITERATIVE GET ITEM

    /**
     * Gets the item at the given index.
     * If no such item exists, returns null.
     * Does not mutate the deque.
     * @param index is an index where 0 is the front.
     * @return the ith item of the deque, null if it does not exist.
     */
    public T iterGet(int index) {
		if(this.sentinel==null||this.size<=0||index<0||index>=this.size) return null;
		Node p = this.sentinel.next;
		for(int i=0;i<=index;i++) {
			if(index==i) return p.item;
			p = p.next;
		}
		return null;
    }


    // ASSIGNMENT 8.1 ADD TO BACK

    /**
     * Adds an item of type T to the back of the deque.
     * @param item is a type T object added to the deque.
     */
    public void addLast(T item) {
    	Node newNode = new Node(null, item, null);
    	newNode.prev = this.sentinel.prev;
    	this.sentinel.prev.next = newNode;
    	this.sentinel.prev = newNode;
    	newNode.next = this.sentinel;
    	this.size += 1;
    }


    // ASSIGNMENT 8.2 DELETE FRONT

    /**
     * Deletes and returns the item at the front of the deque.
     * If no such item exists, returns null.
     * @return the first item of the deque, null if it does not exist.
     */
    public T delFirst() {
    	if(this.sentinel==null||this.size<=0) {
    		return null;
    	}
		T target = this.sentinel.next.item;
		Node f1rst = this.sentinel.next;
		Node next = this.sentinel.next.next;
		next.prev = this.sentinel;
		this.sentinel.next = next;
		f1rst.next = null;
		f1rst.prev = null;
		this.size -= 1;
		return target;
    }


    // ASSIGNMENT 8.3 DELETE BACK

    /**
     * Deletes and returns the item at the back  of the deque.
     * If no such item exists, returns null.
     * @return the last item of the deque, null if it does not exist.
     */
    public T delLast() {
    	if(this.sentinel==null||this.size<=0) {
    		return null;
    	}
    	Node last2Node = this.sentinel.prev.prev;
    	Node targetNode = this.sentinel.prev;
    	T target = targetNode.item;
    	last2Node.next = this.sentinel;
    	this.sentinel.prev = last2Node;
    	targetNode.next = null;
    	targetNode.prev = null;
		return target;
    }


    // ASSIGNMENT 8.4 RECURSIVE GET ITEM

    /**
     * Gets the item at the given index.
     * If no such item exists, returns null.
     * Does not mutate the deque.
     * @param index is an index where 0 is the front.
     * @return the ith item of the deque, null if it does not exist.
     */
    public T recGet(int index) {
    	return recHelper(index, 0, this.sentinel.next);
    }   
	private T recHelper(int index,int now,Node n) {
		if(this.sentinel==null||this.size<=0||index<0||index>=this.size) return null;
		if(now==index) return n.item;
		return recHelper(index, now+1, n.next);
	}

    public static void main(String[] args) {
        LLDeque<String> deque = new LLDeque<>();
        deque.addFirst("b");
        deque.addFirst("a");
        deque.printDeque();
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章