JAVA單鏈表的實現-不帶頭結點且沒有尾指針


本程序采用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;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM