標籤:資料結構 linkedlistjava
上代碼:
package com.itany.MyLinkedList;import java.util.ConcurrentModificationException;import java.util.Iterator;import java.util.NoSuchElementException;public class MyLinkedList<T> implements Iterable<T>{ private int theSize; private int modCount=0; private Node<T> beginMarker; private Node<T> endMarker; public MyLinkedList() { clear(); } private static class Node<T> { private T data; private Node<T> prev; private Node<T> next; public Node(T d,Node<T> p,Node<T> n) { this.data=d; this.prev=p; this.next=n; } } //清除所有內容 實際上就是把集合的begin和end重新賦值一個新的,再把首尾連起來 public void clear() { theSize=0; beginMarker=new Node<T>(null,null,null); endMarker=new Node<T>(null,beginMarker,null); beginMarker.next=endMarker; modCount++; } public boolean isEmpty() { return theSize==0; } public int size() { return theSize; } public void add(T t) { add(size(),t); } public void add(int idx,T t) { addBefore(getNode(idx),t); } public T remove(int idx) { return remove(getNode(idx)); } public T set(int idx,T newT) { Node<T> p=getNode(idx); T old=p.data; p.data=newT; return old; } //所有的add get set remove操作都是對序號進行操作 這要求我們必須在集合內部自己實現通過序號尋找到具體Node 在對Node進行操作的addBefore //remove 和getNode這三個基本方法 注意:這三個頂級類中的基本方法時私人的 外部無法訪問 只能在頂級類內部調用 private void addBefore(Node<T> node,T t) { Node<T> newT=new Node<T>(t,node.prev,node); node.prev.next=newT; node.prev=newT; theSize++; modCount++; } private T remove(Node<T> node) { node.prev.next=node.next; node.next.prev=node.prev; theSize--; modCount++; return node.data; } //因為node中沒有序號 所以要找到對應Index的node必須 使用遍曆 一個個通過預設序號(從0開始)來尋找到 //為了尋找是更快 所以需要對index的大小分類 以確定是從頭開始找還是從末尾 //功能是獲得對應序號的節點 private Node<T> getNode(int idx) { Node<T> p; //idx==size()的情況是有一種add是直接載入鏈表後面順序加入 if(idx<0 || idx>size()) throw new ArrayIndexOutOfBoundsException(); //如果插入的idx序號考前 則從beginMarker開始遍曆 if(idx<size()/2) { p=beginMarker.next; //此處idx是幾迴圈就要走幾次 for(int i=0;i<idx;i++) p=p.next; } //如果插入的idx序號考後 則從endMarker開始遍曆 else { //注意 如果是預設插入到最後 那麼會調用add(t),add(size(),t) 也就是addBefore(node,t) 此處的node就是size()對應的node 即endMarker p=endMarker; //如果插在最後 那麼不會進入for迴圈 for(int i=size();i>idx;i--) p=p.prev; } return p; } public Iterator<T> iterator() { return new LinkedListIterator(); } private class LinkedListIterator implements Iterator<T> { //為了檢測在迭代期間集合被修改的情況是否一致 private int expectedModCount=modCount; //要求必須在next之後才允許刪除 private boolean okToRemove=false; private Node<T> current=beginMarker.next; //別被名字所迷惑了 實際上在此處就是 hasCurrent public boolean hasNext() { return current!=endMarker; } public T next() { if(expectedModCount!=modCount) throw new ConcurrentModificationException(); if(!hasNext()) throw new NoSuchElementException(); T t=current.data; okToRemove=true; current=current.next; return t; } //注意 迭代器的remove是沒有傳回值的 public void remove() { if(!okToRemove) throw new IllegalStateException(); if(expectedModCount!=modCount) throw new ConcurrentModificationException(); MyLinkedList.this.remove(current.prev); okToRemove=false; expectedModCount++; } }}
package com.itany.MyLinkedList;import java.util.Iterator;public class Test{ public static void main(String[] args) { MyLinkedList<Integer> my=new MyLinkedList<Integer>(); my.add(22); my.add(13); my.add(45); my.add(1,15); my.add(7,16); Iterator<Integer> it=my.iterator(); while(it.hasNext()) { System.out.println(it.next()+" "); } } }
資料結構--LinkedList的java實現