@Override public T first() { if (size == 0) { return null; } Node<T> current = head; // traverse to lowest level of head sentinel while (current.getDown() != null) { current = current.getDown(); } return current.getNext().getData(); }
@Override public Set<T> dataSet() { // navigate to bottom level and go through all elements Set<T> set = new HashSet<T>(); Node<T> current = head; while (current.getDown() != null) { current = current.getDown(); } // now should be on bottom level of head sentinel while (current.getNext() != null) { current = current.getNext(); set.add(current.getData()); } return set; }
@Override public void put(T data) { if (data == null) { throw new java.lang.IllegalArgumentException(); } int height = getHeight(); if (height > head.getLevel()) { resizeHead(height); } Node<T> current = head; Node<T> previous = null; // go through each level once for (int level = head.getLevel(); level > 0; level--) { // at max height that should be added if (level == height) { // traverse until next is null or bigger than data, then add while (current.getNext() != null && data.compareTo(current.getNext().getData()) > 0) { current = current.getNext(); } // add after current, update pointers Node<T> newNode = new Node<>(data, level, current.getNext(), null, null); current.setNext(newNode); previous = newNode; // after adding, drop down a level current = current.getDown(); // now at level below max height of added node, update up/down } else if (level < height) { // traverse until next is null or bigger again while (current.getNext() != null && data.compareTo(current.getNext().getData()) > 0) { current = current.getNext(); } // add after current, update next/up/down pointers Node<T> newNode = new Node<>(data, level, current.getNext(), previous, null); current.setNext(newNode); previous.setDown(newNode); previous = newNode; // now drop again, fine if on bottom level current = current.getDown(); // now at higher level than needs to be added, traverse until drop } else { while (current.getNext() != null && data.compareTo(current.getNext().getData()) > 0) { current = current.getNext(); } current = current.getDown(); } } size++; }
@Override public T remove(T data) { if (data == null) { throw new java.lang.IllegalArgumentException(); } T retValue = null; // go through each row, if found on row, pointers pass over Node<T> current = head; for (int level = head.getLevel(); level > 0; level--) { while (current.getNext() != null && data.compareTo(current.getNext().getData()) > 0) { current = current.getNext(); } // next node either null, bigger than data, or a match if (current.getNext() != null && data.equals(current.getNext().getData())) { // match found retValue = current.getNext().getData(); current.setNext(current.getNext().getNext()); } current = current.getDown(); } if (retValue != null) { size--; } return retValue; }
@Override public T last() { if (size == 0) { return null; } Node<T> current = head; while (current.getDown() != null) { while (current.getNext() != null) { current = current.getNext(); } current = current.getDown(); } // now should be on lowest level, traverse to end while (current.getNext() != null) { current = current.getNext(); } return current.getData(); }
@Override public T get(T data) { if (data == null) { throw new java.lang.IllegalArgumentException(); } if (size() == 0) { return null; } Node<T> current = head; for (int level = head.getLevel(); level > 0; level--) { // traverse until next is null or bigger than data, then drop while (current.getNext() != null && data.compareTo(current.getNext().getData()) > 0) { current = current.getNext(); } if (current.getNext() != null && data.equals(current.getNext().getData())) { return current.getNext().getData(); } current = current.getDown(); } return null; }