數據結構學習筆記(二)---單鏈表

單鏈表中結點類型的描述如下:

class LNode {
    Integer data;
    LNode next;
}

1.頭插法建立單鏈表。
從一個空表開始,生成新節點,並將讀取到的數據存放到新節點的數據域中,然後將新節點插入到當前鏈表的表頭,即頭結點之後,如圖所示:

這裏寫圖片描述

算法如下:

public LNode createList1() {
        LNode l = new LNode();
        l.next = null;
        for(int i=0; i<10; i++) {
            LNode tmp = new LNode();
            tmp.data = i;
            tmp.next = l.next;
            l.next = tmp;
        }
        return l;
    }

2.尾插法建立單鏈表
將新節點插入到當前鏈表的表尾,爲此增加一個尾指針r,使其指向當前鏈表的表尾,如圖:

這裏寫圖片描述

算法如下:

    public LNode createList2() {
        LNode l = new LNode();
        LNode r = l;
        for(int i=0; i<10; i++) {
            LNode tmp = new LNode();
            tmp.data = i;
            r.next = tmp;
            r = tmp;
        }

        r.next = null;

        return l;
    }

3.按序號查找節點值。

在單鏈表中從第一個節點出發,順指針next域住個往下搜索,直到找到第i個節點爲止,否則返回最後一個節點指針域NULL。

    public LNode getElem(LNode l, int i) {

        if(i < 1) {     //如果要查找的元素的位置比1還小,返回NUll
            return null;
        }

        int j = 1; 
        LNode p = l.next;

        while(null != p && j < i) {     //從第一個節點開始查找,查找第i個節點
            p = p.next;
            j++;
        }
        return p;   //返回第i個節點的指針,如果i大於表長,p=NULL
    }

4.按值查找表節點
從單鏈表第一個節點開始,由前往後依次比較表中各節點數據域的值,若某節點數據域的值等於給定值e,則返回該節點指針,若整個單鏈表中沒有這樣的節點,則返回NULL。

    public LNode locateElem(LNode l, int e) {
        LNode p = l.next;
        while(null != p && e != p.data) {
            p = p.next;
        }
        return p;
    }

5.插入節點操作

插入操作是將值爲x的新節點插入到單鏈表的第i個位置。首先檢查插入位置的合理性,然後找到待插入位置的前驅節點,即第i-1個元素,再在其後面插入新的節點。
算法首先調用getElem(LNode l)方法查找第i-1個節點,假設返回的第i-1個節點爲p, 然後令新節點s的指針指向p的後繼節點,再令節點p的指針域指向新插入的節點s,如圖所示:

這裏寫圖片描述

(1) p = getElem(l, i-1);
(2) s.next = p.next;
(3) p.next = s;

本算法主要開銷在查找第i-1個元素,時間複雜度爲O(n)。

此外,可以採用另一種方式將其轉換爲後插操作來實現,設帶插入節點爲s,將s插入到p的前面。我們採用將s插入到p的後面的方式,然後將p.data與s.data交換即可,這樣既能滿足邏輯關係,又能使得時間複雜度爲O(1),思想如下:

s.next = p.next;
p.next = s;
temp = p.data;
p.data = s.data;
s.data = temp;

6.刪除節點元素
刪除操作是將單鏈表的第i個節點刪除,先檢查其刪除位置的合法性,然後查找表中第i-1個節點,即被刪除節點的前驅節點,再將其刪除,如下圖所示:

這裏寫圖片描述

假設節點p爲找到的被刪除節點的前驅節點,爲了實現這一操作後的邏輯關係的變化,僅需要修改p的指針域,即將p的指針域next指向q的下一個節點。
代碼片段如下:

p = getElem(l, i-1);
q = p.next;
p.next = q.next;
q.next = null;

和插入算法一樣,時間主要消耗在查找操作上,時間複雜度爲O(n)。

其實,刪除節點p的操作可以用刪除p的後繼節點操作來實現,實質就是將其後繼節點的值賦予其自身,然後刪除後繼節點,使得時間複雜度爲O(1)。

q = p.next;
p.data = q.data; //將後繼元素的值賦予該元素
p.next = q.next;
q.next = null;
發佈了74 篇原創文章 · 獲贊 3 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章