java實現連結串列(模擬LinkedList)
阿新 • • 發佈:2019-01-31
眾所周知,連結串列是由一個個節點連線在一起,這裡我們就先建立一個節點類,為了達到模擬效果,我們選擇建一個Node的靜態內部類。
我們要想模擬LinkedList,就得先了解LinkedList的類包含的方法:
add(Object) dd(int,Object) addFirst addLast get(int index) remove getIndex removeFirst removeLast等
以及LinkedList 所實現的介面
我們為了要使用foreach語句遍歷,就必須實現Iterable介面。附上程式碼:
import java.util.Iterator; public class MyLinkedList<T> implements Iterable<T>{ private Node<T> first;//指向第一個節點的工作指標 private Node<T> current;//指向最後一個節點的工作指標 private int size=0;//統計連結串列長度 private static class Node<T>{ T data; Node<T> next; } //獲取長度 public int size(){ return size; } //新增節點 public void add(T data){ Node<T> newNode=new Node<T>(); newNode.data=data; if(first==null){ first=newNode; current=newNode; size++; return; } current.next=newNode; current=newNode; size++; } //插入第一個位置 public void addFirst(T data){ Node<T> newNode=new Node<T>(); newNode.data=data; if(first==null){ first=newNode; current=newNode; size++; return; } newNode.next=first; first=newNode; size++; } public void addLast(T data){ add(data); } //根據索引新增節點 public void add(int index,T data){ Node<T> newNode=new Node<T>(); newNode.data=data; Node node=getNode(index);//指向指定索引之前的節點 if(node==null){ addFirst(data); return; } newNode.next=node.next; node.next=newNode; size++; } /** * 得到指定索引的資料 * @param index * @return 資料 */ public T get(int index){ return getNode(index).next.data; } /** * 得到指定索引的前一個節點 * @param index * @return */ private Node<T> getNode(int index) { Node<T> node=null; if(index==0){ //插入到第一個 return null; } if(index<size){ //插入中間 node=first; for(int i=1;i<index;i++){ node=node.next; } return node; } return current; } /** * 迭代器 */ public Iterator<T> iterator(){ return new Iterator<T>() { Node<T> cur; @Override public boolean hasNext() { if(cur==null && first!=null){ cur=first; return true; } if(cur.next!=null){ cur=cur.next; return true; } return false; } @Override public T next() { return cur.data; } }; } /** * 移除資料 * @param data */ public void remove(T data){ //查詢資料的索引 int index=getIndex(data); remove(index); } /** * 通過資料查詢第一次出現的索引 * @param data * @return */ private int getIndex(T data) { Node node=first; for(int i=0;i<size;i++){ if(node.data.equals(data)){ return i; } node=node.next; } return -1; } /** * 移除指定索引的資料 * @param index */ public void remove(int index){ Node prev=getNode(index); Node node=getNode(index+1); prev.next=node.next; size--; } /** * 移除第一個 */ public void removeFirst(){ first=first.next; size--; } /** * 移除最後一個 */ public void removeLast(){ //查詢倒數第二個節點 Node node=getNode(size-1); node.next=null; current=node; size--; } /** * 修改指定索引的資料 * @param index * @param newData */ public void set(int index,T newData){ //得到指定索引節點 Node node=getNode(index+1); if(node==null){ node=first; } //修改節點上的資料 node.data=newData; } }
到這裡我們基本模擬了LinkedList類的所有方法,我們趕緊來測試下:
public class Demo { /** * @param args */ public static void main(String[] args) { MyLinkedList<String> list=new MyLinkedList<String>(); list.add("AAA"); list.add("BBB"); list.add("CCC"); list.addFirst("DDD"); list.addLast("EEE"); list.add(2,"FFF"); for(String s:list){ System.out.println(s); } String s=list.get(2); System.out.println("下標為2的元素:"+s); list.set(2, "TEST"); System.out.println("Size:"+list.size()); list.removeFirst(); list.removeLast(); list.remove(2); System.out.println("------------------"); for(String st:list){ System.out.println(st); } } }
這裡我們附上效果圖: