數據結構-線性表-鏈表的代碼詳解

繼上篇文章對順序表的介紹,這篇文章介紹鏈表,作爲數據結構中最重要的一大模塊,鏈表也是以後常用的

單鏈表是其中的核心,理解了單鏈表,其實鏈表的知識你也就掌握了。

代碼附在最後!!!!    思路在程序註釋。詳解

一。

1.代碼部分 一包    三類        節點類,鏈表類,測試類                  在學習過程中可以對着左側行序號更改代碼

2.節點類

3.鏈表類

4.測試類

5.運行結果:

二。代碼附上

Node.java

package LinkList;
/*
 * 定義節點類,後續合成鏈表或者對鏈表進行操作
 * */
public class Node {
//節點儲存的變量
    public int data;
    //指向下一個節點
    public Node next = null;
    public Node(int data) {
        this.data = data;
    }
}
 

LinkedList.java

package LinkList;

/*
 * 定義鏈表模板,將鏈表對象的增刪改查等功能補充完整
 * 有時我們會在鏈表的頭節點之前加一個固定的頭節點表示開始,其可以用來存儲附加信息等
 * 這次的demo我們沒有使用這種頭節點,所以實際實現鏈表以後,頭節點就是真正的數據塊節點
 * */
public class LinkedList {
//定義鏈表的頭節點,因爲鏈表剛建立是空,所以定義頭節點爲null
     Node head = null;
    
    
    //給鏈表添加節點,實質是尋找末尾節點,並將其指向新節點,使新節點的指向爲null
    public void AddNode(int data) {
        Node newNode = new Node(data);
        //尋找並定義末尾節點
        //若head開始便是空的,則證明是空鏈表,直接讓head指向新插入節點,程序結束
        if(head==null) {
            head = newNode;
            return;
        }
        //定義末尾節點temp
        Node temp = head;
        //循環使temp從頭走到null,此時temp指向null的節點爲末尾節點
        while(temp.next!=null) {
            temp = temp.next;
        }
        //將temp指向新插入的節點,如此便實現了鏈表節點的插入
        temp.next=newNode;
    }
    
    //刪除鏈表節點,實質是將要刪除節點的前節點的next指向刪除節點的後節點,從而跳過該節點
    public void DeleteNode(int index) {
        //判斷index是否合法,由此便需要求鏈表的長度length
        if(index<1||index>Length()) {
            try {
                throw new Exception("此位置不合法,無節點可刪除");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //如果刪除位置在頭節點,故直接讓head指向後節點便跳過,不需要執行太多邏輯
        if(index == 1) {
            head = head.next;
        }
        //如果刪除位置不在頭節點,則執行邏輯
        //定義兩個節點,這兩個節點遍歷往後走,當後節點到達所要刪除的節點的位置時
        //將前節點的next指向後節點的next,從而在鏈表結構中跳過index處的節點,實現刪除
        Node preNode = head;
        Node bacNode = preNode.next;
        //定義i計數是否到達index-1處,因爲當i到達index-1的前一處時
        //preNode到達了index-1,bacNode剛好到達index處,所以使preNode.next = bacNode.next剛好跳過index
        int i = 1;
        while(i<index-1) {
            preNode = preNode.next;
            bacNode = bacNode.next;
            i++;
        }
        //到達index處,進行跳過該節點
        preNode.next = bacNode.next;
    }
    
    //打印list值
    public void FindAll() {
        Node newNode = head;
        //此處是節點是否存在而不是節點指向是否爲空
        while(newNode!=null) {
            System.out.println(newNode.data+"  ");
            newNode = newNode.next;
        }
    }
    
    //查詢正數某處節點的值
    public void FindOne(int index) {
        //判斷index是否合法
        if(index<1||index>Length()) {
            return;
        }
        
        Node newNode = head;
        for(int i=0;i<index-1;i++) {
            newNode = newNode.next;
        }
        System.out.println("正數所求的值爲"+newNode.data);
        
    }
    
    //查詢倒數某處節點的值
    public void FindBackOne(int index) {
        //判斷index是否合法
        if(index<1||index>Length()) {
           return;
        }
        //定義前後兩個節點,相距距離爲index,當後節點指向爲null的時候,前節點的data爲所求的值
        Node preNode = head;
        Node backNode = preNode;
        for(int i=1;i<index;i++) {
            backNode = backNode.next;
        }
        
        while(backNode.next!=null) {
            preNode = preNode.next;
            backNode = backNode.next;
        }
        System.out.println("倒數所求值爲"+preNode.data);
    }
    
    //求鏈表的長度
    public int Length() {
        int length = 0;
        //節點從頭遍歷,直到指向null
        //故定義一個節點使其爲頭節點
        Node newNode = head;
        //注意是節點不爲空,而不是指向不爲空
        while(newNode!=null) {
            length++;
            newNode = newNode.next;
        }
        return length;
    }
}
Test.java

package LinkList;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //創建鏈表
        LinkedList la = new LinkedList();
        //鏈表節點插入
        la.AddNode(11);
        la.AddNode(22);
        la.AddNode(33);
        la.AddNode(44);
        la.AddNode(55);
        //鏈表刪除節點
        la.DeleteNode(2);
        
        //正向查找某一結點
        la.FindOne(4);
        //反向查找某一結點
        la.FindBackOne(4);
    
        
        //打印全部節點data
        la.FindAll();
    }

}