3.5 MyLinkedList 實現
阿新 • • 發佈:2020-08-09
3.5 MyLinkedList 類的實現
MyLinkedList 將用雙鏈表實現,並且還需要保留該表兩端的引用。這將需要三個類
- MyLinkedList 類,包含到兩端的鏈、表的大小以及一些方法。
- Node 類 一個私有的巢狀類。一個節點包含資料以及到前一個節點的鏈和到下一個節點的鏈。
- LinkedListIterator 類,是一個私有類,並實現介面 Iterator。提供 next、hasNext 和 remove 的實現。
實現中會在連結串列的頭尾增加額外的標記節點,前端的頭結點和末端的尾節點。如果不使用頭結點,那麼對第 1 個結點的處理就會變成特殊情況,比如刪除時要訪問被刪除節點之前的一個節點。
public class MyLinkedList<E> implements Iterable<E> { private int theSize; private int modCount = 0; private Node<E> beginMarker; private Node<E> endMarker; private static class Node<E> { public E data;//public 訪問屬性也不會破壞封裝,因為Node在MyLinkedList中是private的 public Node<E> prev; public Node<E> next; public Node(E data, Node<E> prev, Node<E> next) { this.data = data; this.prev = prev; this.next = next; } } private void doClear() { this.beginMarker = new Node<E>(null, null, null); this.endMarker = new Node<E>(null, beginMarker, null); beginMarker.next = endMarker; theSize = 0; modCount++; } public MyLinkedList() { doClear(); } public void clear() { doClear(); } public int size() { return theSize; } public boolean isEmpty() { return theSize == 0; } public boolean add(E e) { add(theSize, e); return true; } public void add(int idx, E e) { addBefore(getNode(idx, 0, theSize), e); } public E get(int idx) { return getNode(idx).data; } public E set(int idx, E newVal) { Node<E> p = getNode(idx); E oldVal = p.data; p.data = newVal; return oldVal; } public E remove(int idx) { return remove(getNode(idx)); } private void addBefore(Node<E> p, E e) { Node<E> newNode = new Node<>(e, p.prev, p); newNode.prev.next = newNode; p.prev = newNode; theSize++; modCount++; } private E remove(Node<E> p) { p.next.prev = p.prev; p.prev.next = p.next; theSize--; modCount++; return p.data; } private Node<E> getNode(int idx) { return getNode(idx, 0, theSize - 1); } private Node<E> getNode(int idx, int lower, int upper) { Node<E> p; if (idx < lower || idx > upper) { throw new IndexOutOfBoundsException(); } if (idx < theSize / 2) { p = beginMarker.next; for (int i = 0; i < idx; i++) { p = p.next; } } else { p = endMarker; for (int i = theSize; i > idx; i--) { p = p.prev; } } return p; } public Iterator<E> iterator() { return new LinkedListIterator(); } private class LinkedListIterator implements Iterator<E>{ private Node<E> current = beginMarker.next; private int expectedModCount = modCount; private boolean okToRemove = false; public boolean hasNext() { return current != endMarker; } public E next() { if (modCount != expectedModCount){//避免在使用迭代器時,被迭代器之外的方法修改了List throw new ConcurrentModificationException(); } if(!hasNext()){ throw new NoSuchElementException(); } E nextItem = current.data; current = current.next; okToRemove = true; return nextItem; } public void remove(){ if (modCount != expectedModCount){ throw new ConcurrentModificationException(); } if (!okToRemove){ throw new IllegalStateException(); } MyLinkedList.this.remove(current.prev); expectedModCount++; okToRemove = false; } } }