本程序采用JAVA語言實現了線性表的鏈式實現。首先定義了線性表的接口ListInterface,然后LList類實現了ListInterface完成了鏈表的實現。
本實現中,鏈表是不帶表頭結點的,且有一個指針始終指向鏈表中的第一個元素,並沒有定義尾指針。因此,每次向鏈表中插入新結點時需要遍歷鏈表一次。
更詳細的解釋參考《數據結構與算法分析 JAVA語言描述第二版》Frank M. Carrano 著
ListInterface接口的定義如下:
public interface ListInterface<T> { public boolean add(T newEntry); public boolean add(int givenPosition, T newEntry); public void clear(); public T remove(int givenPosition); public boolean replace(int givenPosition, T newEntry); public T getEntry(int givenPosition); public boolean contains(T anEntry); public int getLength(); public boolean isEmpty(); public void display(); }
具體的實現類LList定義如下:
public class LList<T> implements ListInterface<T>{ private Node firstNode;//指向第一個結點的指針,該鏈表是不帶頭結點的單鏈表 private int length;//表示單鏈表的長度 //Node類中不需要定義訪問屬性的get方法以及set方法,因為Node是內部類,內部類的屬性可以直接在外部類中被訪問 class Node{ //Node是內部類,其外部類中已經定義了T,故可以在這里使用通配符T private T data;//結點的數據部分 private Node next;//結點的指針部分,指向下一個結點 //Node類中不需要默認構造器 public Node(T dataPortion){ data = dataPortion; } public Node(T dataPortion, Node nextNode){ data = dataPortion; next = nextNode; } } public LList(){ clear(); } //獲取鏈表中指定位置處的結點 private Node getNodeAt(int givenPosition){ assert (!isEmpty() && ((1 <= givenPosition) && (givenPosition <= length))); Node currentNode = firstNode; for(int counter = 1; counter < givenPosition; counter++){ currentNode = currentNode.next; } assert currentNode != null; return currentNode; } @Override public boolean add(T newEntry) { // 將每個新結點插入到鏈表的末尾,通過getNodeAt()方法來獲得最后一個元素的地址 Node newNode = new Node(newEntry); if(isEmpty()){//插入第一個結點 firstNode = newNode; } else{//在其它位置插入結點 Node lastNode = getNodeAt(length);//這里每插入一個元素都需要遍歷一次鏈表,代價較大 lastNode.next = newNode; } length++; return true; } @Override public boolean add(int givenPosition, T newEntry){//在指定位置處插入結點 boolean isSuccessful = true; if(givenPosition >= 1 && givenPosition <= length + 1){ Node newNode = new Node(newEntry); if(isEmpty() || givenPosition == 1){//在第一個位置處插入結點 newNode.next = firstNode; firstNode = newNode; } else{//在其它位置插入結點 Node nodeBefore = getNodeAt(givenPosition - 1); Node nodeAfter = nodeBefore.next; nodeBefore.next = newNode; newNode.next = nodeAfter; } length++; } else isSuccessful = false; return isSuccessful; } @Override public final void clear() {//clear()在構造器中被調用了,所以用final修飾 firstNode = null; length = 0; } @Override public T remove(int givenPosition) {//刪除指定位置處的結點 T result = null; if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){ if(givenPosition == 1){//刪除第一個位置處的結點 result = firstNode.data; firstNode = firstNode.next; } else//刪除表中其它位置結點 { Node nodeBefore = getNodeAt(givenPosition - 1); Node nodeToRemove = nodeBefore.next; Node nodeAfter = nodeToRemove.next; nodeBefore.next = nodeAfter; result = nodeToRemove.data; } length--; } return result; } @Override public boolean replace(int givenPosition, T newEntry) {//替換指定位置處結點的值 boolean isSuccessful = true; if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){ Node desireNode = getNodeAt(givenPosition); desireNode.data = newEntry; } else isSuccessful = false; return isSuccessful; } @Override public T getEntry(int givenPosition) {//獲取指定位置的結點的值 T result = null; if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= length))){ result = getNodeAt(givenPosition).data; } return result; } @Override public boolean contains(T anEntry) {//判斷鏈表中的結點是否包含某個值 boolean found = false; Node currentNode = firstNode; while(!found && currentNode != null){ if(currentNode.data.equals(anEntry)){ found = true; break; } currentNode = currentNode.next; } return found; } @Override public int getLength() {//獲取鏈表的長度 return length; } @Override public boolean isEmpty() {//判斷鏈表是否為空 boolean result; if(length == 0){ assert firstNode == null; result = true; } else{ assert firstNode != null; result = false; } return result; } @Override public void display() {//遍歷鏈表,顯示鏈表中的每個結點的值 Node currentNode = firstNode; while(currentNode != null){ System.out.println(currentNode.data); currentNode = currentNode.next; } } }