Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package list;
- import node.NodeI;
- import java.util.NoSuchElementException;
- import java.util.Objects;
- public class LinkedList<T> {
- private T data;
- private LinkedList<T> next = null;
- private NodeI<T> head;
- /*
- The list can either be empty when initialised,
- or the initialisation may contain a head
- */
- //TODO: implement more recursivity, just linked list, w/out node, empty list entity
- //TODO: implement more functionality: addAt, removeAt, findIndexOfElement, getElementAtIndex
- public LinkedList(T data) {
- this.data = data;
- }
- public LinkedList<T> getNext() { return this.next; }
- public void setNext(LinkedList<T> next) {
- this.next = next;
- }
- public T getData() {
- return data;
- }
- public void setData(T data) {
- this.data = data;
- }
- public LinkedList<T> addHead(T data) {
- LinkedList<T> tmp = new LinkedList<>(data);
- tmp.setNext(this);
- return tmp;
- }
- public void addNode(T data) {
- addNode(this, data);
- }
- private void addNode(LinkedList<T> currentNode, T data) {
- if (currentNode.getNext() == null) {
- currentNode.setNext(new LinkedList<>(data));
- return;
- }
- addNode(currentNode.getNext(), data);
- }
- public String toString() {
- return traverse(this);
- }
- private String traverse(LinkedList<T> currentNode) {
- StringBuilder stringBuilder = new StringBuilder(currentNode.getData() + " ");
- if (currentNode.getNext() == null) {
- return stringBuilder.toString();
- }
- stringBuilder.append(traverse(currentNode.getNext()));
- return stringBuilder.toString();
- }
- public int getListSize() {
- return getListSize(this);
- }
- private int getListSize(LinkedList<T> currentNode) {
- if (currentNode.getNext() == null) {
- return 1;
- }
- return 1 + getListSize(currentNode.getNext());
- }
- public LinkedList<T> getNodeAtIndex(int index) {
- int size = getListSize(this);
- if (index > size)
- throw new NoSuchElementException();
- if (index < 0)
- throw new NoSuchElementException();
- LinkedList<T> node = getNodeAtIndex(0, this, index);
- return node;
- }
- private LinkedList<T> getNodeAtIndex(int currentIndex, LinkedList<T> currentNode, int index) {
- if (currentIndex == index) {
- return currentNode;
- }
- return getNodeAtIndex(currentIndex + 1, currentNode.getNext(), index);
- }
- public int getIndexOfNode(LinkedList<T> node) {
- return getIndexOfNode(0, this, node);
- }
- private int getIndexOfNode(int index, LinkedList<T> currentNode, LinkedList<T> node) {
- if (currentNode == null)
- return -1;
- if (currentNode.equals(node)) {
- return index;
- }
- return getIndexOfNode(index + 1, currentNode.getNext(), node);
- }
- public LinkedList<T> removeNode(T node) {
- return removeNode(this, null, node);
- }
- private LinkedList<T> removeNode(LinkedList<T> currentNode, LinkedList<T> previousNode, T node) {
- if (currentNode.getData().equals(node)) {
- //if it's the head of the list
- if (null == previousNode) {
- LinkedList<T> tmp = currentNode;
- currentNode = tmp.getNext();
- return currentNode;
- }
- else {
- previousNode.setNext(currentNode.getNext());
- return previousNode;
- }
- }
- return removeNode(currentNode.getNext(), currentNode, node);
- }
- //TODO: figure out a way to be able to add element as head and as body and not lose the references
- public void addAt(int index, T data) {
- if (!checkIfInBounds(index)) {
- throw new IndexOutOfBoundsException();
- }
- if (index == 0) {
- this.addHead(data);
- return;
- }
- addAt(this, 0, index, data);
- }
- private LinkedList<T> addAt(LinkedList<T> currentNode, int currentIndex, int index, T data) {
- if (currentIndex == index-1) {
- LinkedList<T> node = new LinkedList<>(data);
- node.setNext(currentNode.getNext());
- currentNode.setNext(node);
- return currentNode;
- }
- return addAt(currentNode.getNext(), currentIndex + 1, index, data);
- }
- //TODO: figure out a way to not lose previous node references when removing
- public LinkedList<T> removeAt(int index) {
- if (!checkIfInBounds(index)) {
- throw new IndexOutOfBoundsException();
- }
- return removeAt(this, null, 0, index);
- }
- private LinkedList<T> removeAt(LinkedList<T> currentNode, LinkedList<T> previousNode, int currentIndex, int index) {
- if (currentIndex == index) {
- if (null == previousNode) {
- LinkedList<T> tmp = currentNode;
- currentNode = tmp.getNext();
- return currentNode;
- }
- else {
- previousNode.setNext(currentNode.getNext());
- return previousNode;
- }
- }
- return removeAt(currentNode.getNext(), currentNode, currentIndex + 1, index);
- }
- private boolean checkIfInBounds(int index) {
- return !(index < 0 || index > getListSize());
- }
- //reverse the node order in the list
- public void reverse() {
- NodeI<T> prev = null;
- NodeI<T> current = head;
- NodeI<T> next;
- //the loop that does the reverse itself
- while (null != current) {
- next = current.getNextReference();
- current.setNextReference(prev);
- prev = current;
- current = next;
- }
- head = prev;
- }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- LinkedList<?> that = (LinkedList<?>) o;
- return Objects.equals(getData(), that.getData());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement