package com.coding.basic; public class MyLinkedList implements MyList { private int size = 0; private Node head; private Node tail; @Override public void add(Object o) { if (isEmpty()) { head = new Node(o); tail = head; } else { Node tmp = new Node(o); tail.next = tmp; tmp.prov = tail; tail = tmp; } size++; } @Override public void add(int index, Object o) { checkBoundsForAdd(index); if (index == 0) { addFirst(o); } else if (index == size) { addLast(o); } else { Node pos = findIndexPosition(index); addMid(pos, o); } size++; } /** * add node to the head */ public void addFirst(Object o) { Node tmp = new Node(o); if(head == null){ head = tmp; }else{ tmp.next = head; head.prov = tmp; head = tmp; } } /** * add node to the last */ public void addLast(Object o) { Node tmp = new Node(o); tail.next = tmp; tmp.prov = tail; tail = tmp; } /** * add node to middle position * * @param pos * @param o */ public void addMid(Node pos, Object o) { Node tmp = new Node(o); tmp.prov = pos.prov; pos.prov.next = tmp; tmp.next = pos; pos.prov = tmp; } @Override public Node get(int index) { checkBounds(index); if (index == 0) { return head; } else { Node pos = findIndexPosition(index); return pos; } } @Override public Object remove(int index) { checkBounds(index); Node res; if (index == 0) { res = removeFirst(); } else if (index == size-1) { res = removeLast(); } else { Node pos = findIndexPosition(index); res = removeMid(pos); } size--; return res; } public Node removeFirst() { Node tmp = head; head = head.next; if(head != null){ head.prov = null; } return tmp; } public Node removeLast() { Node tmp = tail; tail = tail.prov; tail.next = null; return tmp; } public Node removeMid(Node pos) { pos.prov.next = pos.next; pos.next.prov = pos.prov; return pos; } @Override public int size() { return size; } public boolean isEmpty() { return head == null; } /** * the index should be within 0~size-1 * * @param index */ public void checkBounds(int index) { if (index < 0 || index > size - 1) { // System.out.println("From MyLinkedList: Index out of bounds"); throw new IndexOutOfBoundsException(OutOfBoundsMsg(index)); } } /** * the index should be within 0~size * * @param index */ public void checkBoundsForAdd(int index) { if (index < 0 || index > size) { // System.out.println("From MyLinkedList: Index out of bounds"); throw new IndexOutOfBoundsException(OutOfBoundsMsg(index)); } } public String OutOfBoundsMsg(int index) { return "Index: " + index + ", Size: " + size; } /** * find the position of index * * @param index * @return */ public Node findIndexPosition(int index) { Node pos = head; for (int i = 0; i < index; i++) { pos = pos.next; } return pos; } @Override public String toString() { String s = ""; Node tmp = head; while (tmp != null) { s += tmp.data + " "; tmp = tmp.next; } return s; } private static class Node { public Object data; public Node prov; public Node next; public Node() { } public Node(Object o) { this.data = o; this.prov = null; this.next = null; } } public MyIterator iterator() { return new LinkedListIterator(this); } private class LinkedListIterator implements MyIterator{ private MyLinkedList eleIterator; private int pos; private LinkedListIterator(MyLinkedList mll){ this.eleIterator = mll; this.pos = 0; } @Override public boolean hasNext() { return pos <= size; } @Override public Object next() { Node res = eleIterator.get(pos); pos++; return res; } } }