简体   繁体   中英

addLast method for a deque with only one sentinel node

This question is from Berkeley's data structures free online course (CS61B) The link can be found here: https://joshhug.gitbooks.io/hug61b/content/chap2/chap23.html

Implement the list so that it is circular, with the front and back pointers sharing the same sentinel node. Add and remove operations must not involve any looping or recursion. A single such operation must take “constant time”, ie execution time should not depend on the size of the deque.

[Box and Pointer Diagram for the allocated task] [1]: https://i.stack.imgur.com/pUgk3.png

Eg if my list is {1,2,3} then sentinel.next.next.item is 3, and sentinel.next.next.next.item is 1

 public class DLList<T> {

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

            public Node(T item, Node next, Node prev) {
                this.item = item;
                this.next = next;
                this.prev = prev;
            }

            @Override
            public String toString() {
                return item.toString();
            }
        }

        public Node sentinel ;
        private int size;

        public DLList() {
            this.sentinel = null;
            this.size = 0;
        }

        public void addLast(T item) {
            sentinel.next = new Node(item, null, sentinel);
            sentinel = sentinel.next;  // updatedSentinel
            size++;
        }
    }

I would just like to ask, how do I make sure the updatedSentinel.next links all the way back to the first node? Also, is my constructor correct for the purposes of this class? Is the implementation supposed to be different when the size is 0 and when the size >= 1?

First,you have to check if the Linked List is empty or not.If it is empty,then link prev,next and sentinel to the current node.

if(head == null)
{
  Node a = new Node(item,a,a);
  sentinel.next = a; 
}

Otherwise find the last node and assign its next node to the first node.Similarly,assign the prev node to the last node.You can keep track of sentinel's next node as head node.

Node head = sentinel.next;
Node last = head;
while(last.next != head)
{
   last = last.next;
}

Node a = new Node(item,head,last);
head.prev = a;
last.next = a;

I don't think there is any mistake with your constructor class.

Make the sentinel point to the last node: it will be null if the list is empty, otherwise, sentinel.next is the first node (because the list is circular). You don't need any backward link. So addLast would be:

    public void addLast(T item) {
        if (sentinel == null) {
            sentinel = new Node(item, null);
            sentinel.next = sentinel;
        } else {
            sentinel.next = new Node(item, sentinel.nex);
            sentinel = sentinel.next;  // updatedSentinel
        }
        size++;
    }

¨ UPDATE: with both links:

    public void addLast(T item) {
        if (sentinel == null) {
            sentinel = new Node(item, null, null);
            sentinel.next = sentinel;
            sentinel.prev = sentinet;
        } else {
            Node next = sentinel.next;
            sentinel.next = next.prev = new Node(item, next, sentinel);
            sentinel = sentinel.next;
        }
        size++;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM