Search code examples
javadata-structureslinked-listdeque

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”, i.e. execution time should not depend on the size of the deque.

[Box and Pointer Diagram for the allocated task] [1]: https://i.sstatic.net/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?


Solution

  • 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++;
        }