(java實現)單鏈表


什么是單鏈表

在了解單鏈表之前,你知道什么是鏈表嗎?如果你不知道什么是鏈表,可以看看我的這篇博客<鏈表-LinkList>

單鏈表是鏈表的其中一種基本結構。一個最簡單的結點結構如圖所示,它是構成單鏈表的基本結點結構。在結點中數據域用來存儲數據元素,指針域用於指向下一個具有相同結構的結點。
因為只有一個指針結點,稱為單鏈表。

單鏈表中三個概念需要區分清楚:分別是頭指針,頭節點和首元節點。

頭結點、頭指針和首元結點(此段轉自@ciyeer大牛的博客)
  • 頭結點:有時,在鏈表的第一個結點之前會額外增設一個結點,結點的數據域一般不存放數據(有些情況下也可以存放鏈表的長度等信息),此結點被稱為頭結點。

若頭結點的指針域為空(NULL),表明鏈表是空表。頭結點對於鏈表來說,不是必須的,在處理某些問題時,給鏈表添加頭結點會使問題變得簡單。
首元結點:鏈表中第一個元素所在的結點,它是頭結點后邊的第一個結點。

  • 頭指針:永遠指向鏈表中第一個結點的位置(如果鏈表有頭結點,頭指針指向頭結點;否則,頭指針指向首元結點)。

  • 頭結點和頭指針的區別:頭指針是一個指針,頭指針指向鏈表的頭結點或者首元結點;頭結點是一個實際存在的結點,它包含有數據域和指針域。兩者在程序中的直接體現就是:頭指針只聲明而沒有分配存儲空間,頭結點進行了聲明並分配了一個結點的實際物理內存。

單鏈表中可以沒有頭結點,但是不能沒有頭指針!
頭節點的引入能使鏈表對第一個元素的刪除和插入和其他元素相同,不用另外說明,使得代碼更加簡潔。

單鏈表的基本操作

單鏈表的基本操作有:增(add),刪(remove),改(set),查(find),插(insert)等。

在這里我們只講解add,remove,insert三個操作,其他實現看源碼。

單鏈表增添元素
  1. 聲明一個新節點node作為新的尾節點,next=null;

  2. 獲取原鏈表的最后一個節點,把它的next指向1步驟的新節點node

  3. 記錄鏈表長度的變量+1

     public void add(AnyType a){
            Node<AnyType> renode=new Node<>(a,null);
            getNode(thesize-1).next=renode;
            thesize++;
        }
單鏈表刪除元素
  1. 獲取需要刪除的節點的上一個節點node

  2. 把node的next指向node的next的next

  3. 因為node的next節點沒有指針指向它,因此它會被系統自動清理

  4. 記錄鏈表長度的變量-1

     public AnyType remove(int i){
        Node<AnyType> prev=getNode(i-1);
        AnyType a=prev.next.data;
        prev.next=prev.next.next;
        thesize--;
        return  a;
    }
單鏈表插入元素
  1. 獲取需要插入的位置的節點;

  2. 聲明一個新節點node指向1步驟得到的節點;

  3. 獲取需要插入位置節點的上一個節點;

  4. 將3步驟得到的節點的next指向新節點node;

  5. 記錄鏈表長度的變量+1。

     public void insert(int i,AnyType a){
            Node<AnyType> prev=getNode(i-1);
            Node<AnyType> renode=new Node<>(a,prev.next);
            prev.next=renode;
            thesize++;
     }

源碼實現(java)

/*
結點
 */
public class Node<AnyType> {
    public  AnyType data;
    public  Node<AnyType> next;
    public Node(AnyType data,Node<AnyType> next){
        this.data=data;
        this.next=next;
    }
}

-----
public class MyLinkList<AnyType> {

    //首元節點
    private Node<AnyType> first;

    //頭指針
    private Node<AnyType> head;

    //鏈表長度
    int thesize;

    //初始化鏈表
    public boolean initlist(){
        thesize=0;
        first=new Node<>(null,null);
        head=new Node<>(null,first);
        return true;
    }

    //判斷鏈表是否為空
    public boolean isEmpty(){
        return thesize==0;
    }

    //獲取節點
    public Node<AnyType> getNode(int i){
        Node<AnyType> renode=head;
        for(int j=-2;j<i;j++){
            renode=renode.next;
        }
        return renode;
    }

    //在末尾添加元素
    public void add(AnyType a){
        Node<AnyType> renode=new Node<>(a,null);
        getNode(thesize-1).next=renode;
        thesize++;
    }

    //刪除i位置節點,並返回刪掉的數據
    public AnyType remove(int i){
        if(i==thesize-1){
            AnyType a=getNode(thesize-1).data;
            getNode(thesize-2).next=null;
            return a;
        }
        Node<AnyType> prev=getNode(i-1);
        AnyType a=prev.next.data;
        prev.next=prev.next.next;
        thesize--;
        return  a;
    }

    //在i位置插入新節點
    public void insert(int i,AnyType a){
        Node<AnyType> prev=getNode(i-1);
        Node<AnyType> renode=new Node<>(a,prev.next);
        prev.next=renode;
        thesize++;
    }

    //獲取i位置節點的數據
    public AnyType get(int i){
        return getNode(i).data;
    }

    //為i位置元素重新賦值
    public void set(int i,AnyType a){
        getNode(i).data=a;
    }

    //返回鏈表節點個數
    public int length(){
        return thesize;
    }

    //清空鏈表
    public void clear(){
        initlist();
    }

    //打印鏈表
    public void print(){
        for(int i=0;i<thesize;i++){
            System.out.println(getNode(i).data);
        }
    }

}


免責聲明!

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



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