數(shù)據(jù)結構--鏈表(C/C++)

概念

?鏈表是一種通過指針串聯(lián)在一起的線性結構舰罚,每一個節(jié)點是由兩部分組成朴肺,一個是數(shù)據(jù)域一個是指針域(存放指向下一個節(jié)點的指針)玷室,最后一個節(jié)點的指針域指向null(空指針的意思)俏扩。

鏈表的類型

1.單鏈表
鏈接的入口點稱為列表的頭結點也就是head花颗。


2.雙鏈表
單鏈表中的節(jié)點只能指向節(jié)點的下一個節(jié)點丈积。而雙鏈表每一個節(jié)點有兩個指針域筐骇,一個指向下一個節(jié)點,一個指向上一個節(jié)點江滨。
雙鏈表既可以向前查詢也可以向后查詢铛纬。

鏈表的存儲方式

?數(shù)組是在內(nèi)存中是連續(xù)分布的,但是鏈表在內(nèi)存中可不是連續(xù)分布的唬滑。鏈表是通過指針域的指針鏈接在內(nèi)存中各個節(jié)點告唆。所以鏈表中的節(jié)點在內(nèi)存中不是連續(xù)分布的 莫秆,而是散亂分布在內(nèi)存中的某地址上,分配機制取決于操作系統(tǒng)的內(nèi)存管理悔详。

鏈表的定義

// 單鏈表  
struct ListNode {  
    int val;  // 節(jié)點上存儲的元素  
    ListNode *next;  // 指向下一個節(jié)點的指針  
    ListNode(int x) : val(x), next(NULL) {}  // 節(jié)點的構造函數(shù)  
};  

同樣我們可以使用C++默認生成的構造函數(shù)镊屎,但是這個構造函數(shù)不會初始化任何成員變化。下面兩段程序可以體現(xiàn)對比茄螃。

ListNode* head = new ListNode(5);  

下面這個使用默認構造函數(shù)

ListNode* head = new ListNode();  
head->val = 5;  

所以如果不定義構造函數(shù)使用默認構造函數(shù)的話缝驳,在初始化的時候就不能直接給變量賦值。

鏈表的常用操作實現(xiàn)

  • get(index):獲取鏈表中第 index 個節(jié)點的值归苍。如果索引無效用狱,則返回-1。
  • addAtHead(val):在鏈表的第一個元素之前添加一個值為 val 的節(jié)點拼弃。插入后夏伊,新節(jié)點將成為鏈表的第一個節(jié)點。
  • addAtTail(val):將值為 val 的節(jié)點追加到鏈表的最后一個元素吻氧。
  • addAtIndex(index,val):在鏈表中的第 index 個節(jié)點之前添加值為 val 的節(jié)點溺忧。如果 index 等于鏈表的長度,則該節(jié)點將附加到鏈表的末尾盯孙。如果 index 大于鏈表長度鲁森,則不會插入節(jié)點。如果index小于0振惰,則在頭部插入節(jié)點歌溉。
  • deleteAtIndex(index):如果索引 index 有效,則刪除鏈表中的第 index 個節(jié)點骑晶。
class MyLinkedList {  
public:  
    // 定義鏈表節(jié)點結構體  
    struct LinkedNode {  
        int val;  
        LinkedNode* next;  
        LinkedNode(int val):val(val), next(nullptr){}  
    };  

    // 初始化鏈表  
    MyLinkedList() {  
        _dummyHead = new LinkedNode(0); // 這里定義的頭結點 是一個虛擬頭結點痛垛,而不是真正的鏈表頭結點  
        _size = 0;  
    }  

    // 獲取到第index個節(jié)點數(shù)值,如果index是非法數(shù)值直接返回-1桶蛔, 注意index是從0開始的匙头,第0個節(jié)點就是頭結點  
    int get(int index) {  
        if (index > (_size - 1) || index < 0) {  
            return -1;  
        }  
        LinkedNode* cur = _dummyHead->next;  
        while(index--){ // 如果--index 就會陷入死循環(huán)  
            cur = cur->next;  
        }  
        return cur->val;  
    }  

    // 在鏈表最前面插入一個節(jié)點,插入完成后羽圃,新插入的節(jié)點為鏈表的新的頭結點  
    void addAtHead(int val) {  
        LinkedNode* newNode = new LinkedNode(val);  
        newNode->next = _dummyHead->next;  
        _dummyHead->next = newNode;  
        _size++;  
    }  

    // 在鏈表最后面添加一個節(jié)點  
    void addAtTail(int val) {  
        LinkedNode* newNode = new LinkedNode(val);  
        LinkedNode* cur = _dummyHead;  
        while(cur->next != nullptr){  
            cur = cur->next;  
        }  
        cur->next = newNode;  
        _size++;  
    }  
  
    // 在第index個節(jié)點之前插入一個新節(jié)點乾胶,例如index為0,那么新插入的節(jié)點為鏈表的新頭節(jié)點朽寞。  
    // 如果index 等于鏈表的長度,則說明是新插入的節(jié)點為鏈表的尾結點  
    // 如果index大于鏈表的長度斩郎,則返回空  
    void addAtIndex(int index, int val) {  
        if (index > _size) {  
            return;  
        }  
        LinkedNode* newNode = new LinkedNode(val);  
        LinkedNode* cur = _dummyHead;  
        while(index--) {  
            cur = cur->next;  
        }  
        newNode->next = cur->next;  
        cur->next = newNode;  
        _size++;  
    }  

    // 刪除第index個節(jié)點脑融,如果index 大于等于鏈表的長度,直接return缩宜,注意index是從0開始的  
    void deleteAtIndex(int index) {  
        if (index >= _size || index < 0) {  
            return;  
        }  
        LinkedNode* cur = _dummyHead;  
        while(index--) {  
            cur = cur ->next;  
        }  
        LinkedNode* tmp = cur->next;  
        cur->next = cur->next->next;  
        delete tmp;  
        _size--;  
    }  

    // 打印鏈表  
    void printLinkedList() {  
        LinkedNode* cur = _dummyHead;  
        while (cur->next != nullptr) {  
            cout << cur->next->val << " ";  
            cur = cur->next;  
        }  
        cout << endl;  
    }  
private:  
    int _size;  
    LinkedNode* _dummyHead;  

};  

文章參考引用:
https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ
https://mp.weixin.qq.com/s/Cf95Lc6brKL4g2j8YyF3Mg
(如有侵權請聯(lián)系刪除)

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肘迎,一起剝皮案震驚了整個濱河市甥温,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌妓布,老刑警劉巖姻蚓,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匣沼,居然都是意外死亡狰挡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門释涛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來加叁,“玉大人,你說我怎么就攤上這事唇撬∷埃” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵窖认,是天一觀的道長豫柬。 經(jīng)常有香客問我,道長扑浸,這世上最難降的妖魔是什么轮傍? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮首装,結果婚禮上创夜,老公的妹妹穿的比我還像新娘。我一直安慰自己仙逻,他們只是感情好驰吓,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著系奉,像睡著了一般檬贰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缺亮,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天翁涤,我揣著相機與錄音,去河邊找鬼萌踱。 笑死葵礼,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的并鸵。 我是一名探鬼主播鸳粉,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼园担!你這毒婦竟也來了届谈?” 一聲冷哼從身側響起枯夜,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艰山,沒想到半個月后湖雹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡曙搬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年摔吏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片织鲸。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡舔腾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搂擦,到底是詐尸還是另有隱情稳诚,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布瀑踢,位于F島的核電站扳还,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏橱夭。R本人自食惡果不足惜氨距,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望棘劣。 院中可真熱鬧俏让,春花似錦、人聲如沸茬暇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糙俗。三九已至勒奇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間巧骚,已是汗流浹背赊颠。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留劈彪,地道東北人竣蹦。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像粉臊,于是被迫代替她去往敵國和親草添。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348