Java实现带头节点的双向循环队列(链表)

Deque

●queue 是一种数据结构,该数据结构允许在队头添加节点,然后在队尾删除一个项,以实现先进先出(FIFO)。

●在这个实验中,我们将创建一个更通用的数据结构,称为 deque,是双端队列的缩写。

●在一个 deque 中,您可以添加和删除两端的项(无论是其前端还是后端)。

○在本实验室,您将完成包括添加和删除在内的许多方法。

●此外,您必须使用通用类型,以便可以实例化 deque 来存储任何类型的对象。

我们将使用链表实现一个 deque,特别是循环链表。

Java实现带头节点的双向循环队列(链表)_第1张图片

1. LLDeque EMPTY CONSTRUCTOR

●完成空的 deque 构造函数 public LLDeque()

●它创造了一个空的 deque

Java实现带头节点的双向循环队列(链表)_第2张图片

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 {

    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 deque = new LLDeque<>();
        deque.addFirst("b");
        deque.addFirst("a");
        deque.printDeque();
    }

}

 

你可能感兴趣的:(Java,数据结构)