package list; /** * @author jiaxun */ public class SinglyLinkedList implements List { private Node head; private int size; public SinglyLinkedList() { size = 0; } public void addFirst(Object data) { Node node = new Node(data); node.setNext(head); head = node; size++; } public Node removeFirst() { Node object = head; head = object.getNext(); size--; return object; } public Node removeLast() { Node curr = head; Node prev = null; while (curr != null) { prev = curr; curr = curr.getNext(); } if (prev != null) { prev.setNext(null); } size--; return curr; } public Node get(int index) { if (index > size) { throw new IndexOutOfBoundsException(); } Node curr = head; while (curr != null) { if (index == 0) break; curr = curr.getNext(); index--; } return curr; } public Node remove(int index) { Node curr = head; Node prev = null; while (curr != null) { if (index == 0) break; prev = curr; curr = curr.getNext(); index--; } if (prev != null) { prev.setNext(curr.getNext()); curr.setNext(null); } size--; return curr; } public void addLast(Object object) { if (head == null) { head = new Node(object); } else { Node curr = head; Node prev = null; while (curr != null) { prev = curr; curr = curr.getNext(); } prev.setNext(new Node(object)); } size++; } @Override public void add(Object o) { addLast(o); } public void add(int index, Object object) { Node curr = head; Node prev = null; while (curr != null) { if (index == 0) break; prev = curr; curr = curr.getNext(); index--; } if (prev != null) { Node newNode = new Node(object); newNode.setNext(curr); prev.setNext(newNode); size++; } } public int size() { return size; } public Iterator iterator() { return new SinglyLinkedListIterator(this); } public void reverse() { if (head == null || head.getNext() == null) return; Node prev = null; Node next = null; Node curr = head; while (curr != null) { next = curr.getNext(); curr.setNext(prev); prev = curr; curr = next; } head = prev; } public void removeFirstHalf() { if (head == null) return; int half = size / 2; Node curr = head; while (half != 0) { curr = curr.getNext(); half--; } head = curr; } public void remove(int i, int length) { if (head == null || length == 0 || i >= size) return; if (i + length >= size) length = size - i - 1; Node prev = head; Node curr = head; int firstPos = i; while (curr != null) { if (firstPos == 0) break; prev = curr; curr = curr.getNext(); firstPos--; } int lastPos = length - i; while (curr != null) { if (lastPos == 0) break; curr = curr.getNext(); lastPos--; } prev.setNext(curr == null ? null : curr.getNext()); } public int[] getElements(SinglyLinkedList list) { if (list == null || list.size() == 0) return null; int[] resultList = new int[list.size()]; int offset = 0; int count = 0; Node curr = head; for (int i = 0, len = list.size(); i < len; i++) { int index = (int) list.get(i).getData(); index = index - offset; offset = (int) list.get(i).getData(); while (curr != null) { if (index == 0) { resultList[count++] = (int) curr.getData(); break; } curr = curr.getNext(); index--; } } return resultList; } public void subtract(SinglyLinkedList list) { if (head == null || list == null) return; Node curr = head; Node prev = null; int bCount = 0; while (curr != null) { if (bCount == list.size()) break; int currData = (int) curr.getData(); int bData = (int) list.get(bCount).getData(); if (currData == bData) { if (prev != null) { prev.setNext(curr.getNext()); } else { head = curr.getNext(); } bCount++; } else { prev = curr; } curr = curr.getNext(); } } public void removeDuplicateValues() { if (size <= 1) return; Node prev = head; Node curr = head.getNext(); while (curr != null) { if (prev.getData().equals(curr.getData())) { if (curr.getNext() != null) { curr = curr.getNext(); } else { curr = curr.getNext(); prev.setNext(null); } } else { prev.setNext(curr); prev = curr; curr = curr.getNext(); } } } public void removeRange(int min, int max) { if (head == null || (int) head.getData() > max) return; Node prev = null; Node next = null; Node curr = head; boolean lessHead = false; if ((int) head.getData() > min) { prev = head; lessHead = true; } while (curr != null) { int data = (int) curr.getData(); if (!lessHead && data < min) { prev = curr; } if (data > max) { next = curr; } curr = curr.getNext(); } if (prev != null) { if (prev == head && lessHead) { head = next; } else { prev.setNext(next); } } } public SinglyLinkedList intersection(SinglyLinkedList list) { SinglyLinkedList resultList = new SinglyLinkedList(); Node aCurr = head; Node bCurr = list.head; while (aCurr != null && bCurr != null) { int a = (int) aCurr.getData(); int b = (int) bCurr.getData(); if (a < b) { resultList.add(aCurr.getData()); aCurr = aCurr.getNext(); } else if (a > b) { resultList.add(bCurr.getData()); bCurr = bCurr.getNext(); } else { resultList.add(aCurr.getData()); aCurr = aCurr.getNext(); bCurr = bCurr.getNext(); } } while (aCurr != null) { resultList.add(aCurr.getData()); aCurr = aCurr.getNext(); } while (bCurr != null) { resultList.add(bCurr.getData()); bCurr = bCurr.getNext(); } return resultList; } @Override public String toString() { StringBuilder builder = new StringBuilder(); Node current = head; while (current != null) { builder.append(current.toString()); current = current.getNext(); } return builder.toString(); } private class SinglyLinkedListIterator implements Iterator { private SinglyLinkedList linkedList; private int currentPosition = 0; public SinglyLinkedListIterator(SinglyLinkedList linkedList) { this.linkedList = linkedList; } @Override public boolean hasNext() { return currentPosition < size; } @Override public Object next() { return linkedList.get(currentPosition++); } @Override public Object remove() { return linkedList.remove(--currentPosition); } } public static class Node { private Object data; private Node next; public Node(Object data) { this.data = data; } public Object getData() { return data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } @Override public String toString() { return "[data is " + getData() + "]"; } } }