How to do a cyclic doubly link list add method in java

后端 未结 3 574
孤城傲影
孤城傲影 2021-01-28 16:24

I am implementing the add(E) method in the cyclic DoublyLinkedList class as well as the Node inner class.

Node should be implemented as a private inner class.

D

相关标签:
3条回答
  • 2021-01-28 17:01

    Code fixed with minimal change (just the else case in add):

    class DoublyLinkedList<E>
    {
        private Node first;
        private int size;
    
        public void add(E value)
        {
            if(first == null)
            {
                first = new Node(value, null, null);
                first.next = first;
                first.prev = first;
            }
            else
            {
                first.prev.next = new Node(value, first, first.prev);
                first.prev = first.prev.next;
            }
            size++;
        }
    
        private class Node<E>
        {
            private E data;
            private Node next;
            private Node prev;
    
            public Node(E data, Node next, Node prev)
            {
                this.data = data;
                this.next = next;
                this.prev = prev;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-28 17:17

    EDIT:

    One mistake is here: Instead of this line this.next = prev; it should have this.prev = prev;

    However, if you fix this line the code will still not work. This is a simplified version of your code that works.

    public class DoublyLinkedList<E> {
    
        private static class Node<E> {
    
            private final E data;
            private Node<E> next;
            private Node<E> prev;
    
            Node(E data) {
                this.data = data;
                this.next = this;
                this.prev = this;
            }
    
            Node(E data, Node<E> next) {
                this.data = data;
                this.next = next;
                next.prev = this;
            }
        }
    
        private Node<E> head;
        private Node<E> tail;
        private int size;
    
        public void add(E value) {
            if (this.head == null) {
                this.head = new Node<>(value);
                this.tail = head;
            } else {
                this.head = new Node<>(value, head);
                this.head.prev = this.tail;
                this.tail.next = head;
            }
            size++;
        }
    
        public void forEach(Consumer<E> consumer) {
            Node<E> node = this.head;
    
            if (node != null) {
                do {
                    consumer.accept(node.data);
                    node = node.next;
                } while (node != this.head);
            }
        }
    
        public static void main(String[] args) {
            DoublyLinkedList<Integer> list = new DoublyLinkedList<>();
    
            list.add(1);
            list.add(2);
            list.add(3);
    
            list.forEach(e -> System.out.print(e + ", "));
        }
    
    }
    

    What I've done: in order to create a circular double linked list I keep a reference to the tail.

    0 讨论(0)
  • 2021-01-28 17:19

    Here is a sample implementation for your case -

    import java.util.Iterator;
    
    public class DoublyLinkedList<E> {
    
        // A reference to the root node
        private Node<E> root = null;
    
        // attribute for storing the size of the linked list
        private int countOfNodes = 0;
    
        // attribute that indicates if the linked list would be iterated in a cycle
        private boolean isCircular = false;
    
        /**
         * The linked list Node class
         * 
         * @param <E>
         */
    
        @SuppressWarnings("hiding")
        class Node<E> {
            // attribute for storing the value
            private E data;
    
            // attributes for storing the linked list references
            private Node<E> previousNode = null;
            private Node<E> nextNode = null;
    
            public Node() {
                super();
            }
    
            public Node(E data) {
                super();
                this.data = data;
            }
    
            public Node<E> getPreviousNode() {
                return previousNode;
            }
    
            public void setPreviousNode(Node<E> previousNode) {
                this.previousNode = previousNode;
            }
    
            public Node<E> getNextNode() {
                return nextNode;
            }
    
            public void setNextNode(Node<E> nextNode) {
                this.nextNode = nextNode;
            }
    
            public E getData() {
                return data;
            }
    
            public void setData(E data) {
                this.data = data;
            }
        }
    
        /**
         * The iterator implementation
         */
        @SuppressWarnings("hiding")
        class DoublyLinkedListIterator<E> implements Iterator<E> {
            private Node<E> currentNode = null;
    
            public DoublyLinkedListIterator(Node<E> startNode) {
                super();
                this.currentNode = startNode;
            }
    
            @Override
            public boolean hasNext() {
                return (this.currentNode != null);
            }
    
            @SuppressWarnings("unchecked")
            @Override
            public E next() {
                E data = currentNode.getData();
                currentNode = currentNode.getNextNode();
    
                if (currentNode == null && DoublyLinkedList.this.isCircular()) {
                    this.currentNode = (Node<E>) DoublyLinkedList.this.getRoot();
                }
    
                return data;
            }
        }
    
        public DoublyLinkedList() {
            super();
        }
    
        public boolean isCircular() {
            return this.isCircular;
        }
    
        public void setCircular(boolean isCircular) {
            this.isCircular = isCircular;
        }
    
        public Node<E> getRoot() {
            return root;
        }
    
        public void setRoot(Node<E> root) {
            this.root = root;
        }
    
        public int size() {
            return this.countOfNodes;
        }
    
        public Iterator<E> iterator() {
            return new DoublyLinkedListIterator<>(this.getRoot());
        }
    
        public void add(E value) {
            Node<E> node = new Node<E>(value);
            addAfter(getLastNode(), node);
            this.countOfNodes++;
        }
    
        public Node<E> getLastNode() {  
            Node<E> lastNode = null;
    
            Node<E> node = getRoot();
            while (node != null) {
                lastNode = node;
                node = node.getNextNode();
            }
    
            return lastNode;
        }
    
        public void addAfter(Node<E> parentNode, E value) {
            Node<E> newNode = new Node<E>(value);
            addAfter(parentNode, newNode);
        }
    
        public void addAfter(Node<E> parentNode, Node<E> newNode) {
            if (parentNode == null) {
                this.setRoot(newNode);
            } else {
                parentNode.setNextNode(newNode);
            }
        }
    
        public void addBefore(Node<E> parentNode, E value) {
            Node<E> newNode = new Node<E>(value);
            addBefore(parentNode, newNode);
        }
    
        public void addBefore(Node<E> parentNode, Node<E> newNode) {
            if (parentNode == null) {
                this.setRoot(newNode);
            } else {
                Node<E> prevNode = parentNode.getPreviousNode();
                parentNode.setPreviousNode(newNode);
                newNode.setNextNode(parentNode);            
                newNode.setPreviousNode(prevNode);
    
                if (newNode.getPreviousNode() == null) {
                    this.setRoot(newNode);
                }
            }
        }
    }
    

    And, following is a test -

    import static org.junit.jupiter.api.Assertions.fail;
    
    import java.util.Iterator;
    
    import org.junit.jupiter.api.Test;
    
    class DoublyLinkedListTest {
        private final int initialSize = 4;
    
        private DoublyLinkedList<String> list = new DoublyLinkedList<String>() {{
            setCircular(true);
    
            for(int i = 0; i < initialSize; i++) {
                add("Data " + (i + 1));
            }
        }};
    
        public DoublyLinkedListTest() {
            super();
        }
    
        @Test
        void testListSize() {
            if (list.size() != initialSize) {
                fail(String.format("Expected value for the list's size is %d, whereas obtained value is %d", 4, list.size()));
            }
        }
    
        @Test
        void testLastElement() {
            String lastAddedValue = list.getLastNode().getData();
            String expectedValue = "Data 4";
    
            if (!expectedValue.equals(lastAddedValue)) {
                fail(String.format("Expected value for the last node is %s, whereas obtained value is %s", expectedValue, lastAddedValue));
            }
        }
    
        @Test
        void testAddElementOnTop() {
            list.addBefore(list.getRoot(), "Data 5");
    
            String lastAddedValue = list.getRoot().getData();
            String expectedValue = "Data 5";
    
            if (!expectedValue.equals(lastAddedValue)) {
                fail(String.format("Expected value for the last node is %s, whereas obtained value is %s", expectedValue, lastAddedValue));
            }
        }
    
        @Test
        void testCircularIteration() {
            Iterator<String> iterator = list.iterator();
    
            int counter = 0;
            final int expectedValue = (initialSize + 1) * 2;
    
            while(iterator.hasNext()) {
                counter++;
    
                if (counter == expectedValue) {
                    break;
                }
            }
    
            if (counter != expectedValue) {
                fail(String.format("Expected value for the iteration count is %d, whereas obtained value is %d", expectedValue, counter));
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题