數(shù)據(jù)結(jié)構(gòu) ——基于鏈式存儲結(jié)構(gòu)的線性表

鏈式存儲的定義

鏈式存儲為了表示數(shù)據(jù)元素與其直接后繼元素間的邏輯關(guān)系凌摄,數(shù)據(jù)元素除了存儲本身的信息外,還需要存儲直接后繼的信息。相連的數(shù)據(jù)元素之間在存儲空間中不要求連續(xù)狈惫。

鏈式存儲的邏輯結(jié)構(gòu)
基于鏈式存儲結(jié)構(gòu)的線性表中,每個節(jié)點都包含數(shù)據(jù)域和指針域鹦马。數(shù)據(jù)域用于存儲數(shù)據(jù)元素本身胧谈,指針域用于存儲相鄰節(jié)點的地址。

image.png

一個完整的鏈表需要由以下幾部分構(gòu)成:

  • 頭指針:
    一個普通的指針荸频,它的特點是永遠指向鏈表第一個節(jié)點的位置菱肖。很明顯,頭指針用于指明鏈表的位置旭从,便于后期找到鏈表并使用表中的數(shù)據(jù)稳强;
  • 節(jié)點:
    鏈表中的節(jié)點又細分為頭節(jié)點、首元節(jié)點和其他節(jié)點:
    頭節(jié)點:
    其實就是一個不存任何數(shù)據(jù)的空節(jié)點和悦,通常作為鏈表的第一個節(jié)點退疫。對于鏈表來說,頭節(jié)點不是必須的鸽素,它的作用只是為了方便解決某些實際問題褒繁;
完整的鏈表示意圖

線性表的基本操作方式

        LinkList();                                             //構(gòu)造函數(shù),初始化線性表
        virtual ~LinkList();                                    //析構(gòu)函數(shù)馍忽。銷毀線性表
        void ClearList();                                       //清空線性表
        bool listisEmpty();                                     //判斷線性表是否為空
        int ListLength();                                       //獲取線性表的長度
        bool GetElem(int i,Node *pNode);                        //獲取指定元素
        int LocateElem(Node *pNode);                            //尋找第一個滿足的數(shù)據(jù)元素的位序
        bool PriorElem(Node *pcurrentNode,Node *pPreNode);      //獲取指定節(jié)點的前驅(qū)
        bool NextElem(Node *pcurrentNode,Node *pNextNode);      //后去指定節(jié)點的后驅(qū)
        bool ListInsert(int i,Node *pNode);                     //在指定位置插入節(jié)點
        bool ListDelete(int i,Node *pNode);                     //刪除指定位置的節(jié)點
        bool ListInsertHead(Node *pNode);                       //在頭節(jié)點插入新的節(jié)點
        bool ListInsrtTail(Node *pNode);                        //在尾節(jié)點插入新的節(jié)點
        void ListTraverse();

在頭節(jié)點插入新的節(jié)點操作

在鏈表頭節(jié)點插入新節(jié)點存在兩種情況
1棒坏、鏈表本身是空表

  • 即鏈表的新節(jié)點的next指針會指向null,然后操作LinkedList對象的頭指針指向新的節(jié)點遭笋,完成鏈表頭節(jié)點插入新節(jié)點動作坝冕。

2、鏈表本身已含其他節(jié)點

  • 即鏈表的新節(jié)點的next指針會指向LinkedList對象的頭指針指向的節(jié)點坐梯,然后操作LinkedList對象的頭指針指向新的節(jié)點徽诲,完成鏈表頭節(jié)點插入新節(jié)點動作。
//在鏈表的頭部插入結(jié)點
bool LinkList::ListInsertHead(Node *pNode)
{
    Node *temp = m_pList->next;         //將頭節(jié)點保存一個新的臨時節(jié)點中
    
    Node *newNode = new Node;               //堆中申請內(nèi)存
    if(newNode == NULL)
    {
        return false;
    }
    newNode->data = pNode->data;
    m_pList->next = newNode;            //頭節(jié)點指向新申請的節(jié)點
    newNode->next = temp;               //新申請的節(jié)點指針域
    m_iLength++;
    return true;
}

在末端插入元素操作

將要插入的節(jié)點放在鏈表中最后一個節(jié)點吵血,因此該節(jié)點的next指針需要指向NULL

//在鏈表的尾部插入結(jié)點
bool LinkList::ListInsrtTail(Node *pNode)
{
    Node *currentNode = m_pList;
    while(currentNode ->next != NULL)     //遍歷最后一個節(jié)點
    {
        currentNode = currentNode->next;
    }
    Node *newNode = new Node;               //堆中申請內(nèi)存
    if(newNode == NULL)
    {
        return false;
    }
    //最后一個節(jié)點的next指向新創(chuàng)建的節(jié)點谎替。
    newNode->data = pNode->data;            //
    newNode->next = NULL;                   //指向空作為最后一個節(jié)點
    currentNode->next = newNode;
    m_iLength++;                                    //鏈表長度加一
    return true;
}

往鏈表中的任意位置插入新節(jié)點操作

插入新節(jié)點操作需遍歷到第i-1個節(jié)點,插入前需要將一個臨時指針副本偏移到指定索引的位置,第i-1個位置的節(jié)點的next指針需要指向新的節(jié)點蹋辅,新的節(jié)點的next指針需要指向原來第i-1個位置的節(jié)點的next指針

//往鏈表中任意位置插入節(jié)點
bool LinkList::ListInsert(int i,Node *pNode)
{
    if(i < 0 || i > m_iLength) return false;

    Node *currentNode = m_pList;//找到頭結(jié)點并保存到currentNode

    for(int j = 0;j<i;j++)      //遍歷到第i-1個節(jié)點,因為插入前需要將一個臨時指針副本偏移到指定索引的位置,需要注意的
    {
        currentNode = currentNode->next;
    }
    Node *newNode = new Node;
    if(newNode == NULL)
    {
        return false;
    }
    newNode->data = pNode->data;            //賦值
    newNode->next = currentNode->next;      //原來currentNode的下一個節(jié)點變成了newNode的下一個節(jié)點
    currentNode->next = newNode;            //再把newNode成為urrentNode的下一個節(jié)點
    m_iLength++;
    return true;
}

鏈表中刪除節(jié)點

此時與插入節(jié)點操作不同的最大不同的是遍歷到第i個節(jié)點钱贯,因為對于單向鏈表來說,一但我們的遍歷的指針位于第i個節(jié)點時已經(jīng)無法返回到位于i-1位置的節(jié)點,此時我們將位于第i個位置的節(jié)點執(zhí)行delete操作侦另,那么第i-1個位置的節(jié)點與第k+1個位置的節(jié)點本應(yīng)要建立的鏈接關(guān)系已經(jīng)無法建立秩命,那么從第k+1個位置的節(jié)點算起的部分與鏈表就“斷鏈”尉共,造成鏈表內(nèi)存泄漏。

bool LinkList::ListDelete(int i,Node *pNode)
 {
    if(i < 0 || i >= m_iLength) return false;

    Node *currentNode = m_pList;//找到頭結(jié)點并保存到currentNode
    Node *currentNodeBefore = NULL;
    for(int j = 0;j<=i;j++)     //遍歷到第i個節(jié)點
    {
        currentNodeBefore = currentNode;  //臨時指針副本偏移到指定索引的第i個位置
        currentNode = currentNode->next;   //遍歷操作
    }
    currentNodeBefore->next = currentNode->next;
    pNode->data = currentNode->data;
    delete currentNode;
    currentNode = NULL;
    m_iLength--;
     return true;
 }

清空鏈表操作

清空鏈表弃锐,我們從頭鏈表的頭部元素一直遍歷到鏈表的末端,遍歷過程中,在每次循環(huán)偏移鏈表的頭指針時,我們需要一個臨時指針變量來緩存前一個節(jié)點然后對其執(zhí)行內(nèi)存釋放操作袄友。

//清空鏈表操作
void LinkList::ClearList()
{
    //刪除節(jié)點
   Node *currentNode =  m_pList->next ;
   while( currentNode != NULL)
   {
     Node *temp = currentNode->next;
     delete currentNode;
     currentNode = temp;
   }
   m_pList ->next =NULL;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市霹菊,隨后出現(xiàn)的幾起案子剧蚣,更是在濱河造成了極大的恐慌,老刑警劉巖旋廷,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸠按,死亡現(xiàn)場離奇詭異,居然都是意外死亡饶碘,警方通過查閱死者的電腦和手機目尖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扎运,“玉大人瑟曲,你說我怎么就攤上這事『乐危” “怎么了测蹲?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鬼吵。 經(jīng)常有香客問我扣甲,道長,這世上最難降的妖魔是什么齿椅? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任琉挖,我火速辦了婚禮,結(jié)果婚禮上涣脚,老公的妹妹穿的比我還像新娘示辈。我一直安慰自己,他們只是感情好遣蚀,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布矾麻。 她就那樣靜靜地躺著,像睡著了一般芭梯。 火紅的嫁衣襯著肌膚如雪险耀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天玖喘,我揣著相機與錄音甩牺,去河邊找鬼。 笑死累奈,一個胖子當著我的面吹牛贬派,可吹牛的內(nèi)容都是我干的急但。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼搞乏,長吁一口氣:“原來是場噩夢啊……” “哼波桩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起请敦,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤突委,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冬三,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡缘缚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年勾笆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桥滨。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡窝爪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出齐媒,到底是詐尸還是另有隱情蒲每,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布喻括,位于F島的核電站邀杏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏唬血。R本人自食惡果不足惜望蜡,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拷恨。 院中可真熱鬧脖律,春花似錦、人聲如沸腕侄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽冕杠。三九已至微姊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間分预,已是汗流浹背柒桑。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留噪舀,地道東北人魁淳。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓飘诗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親界逛。 傳聞我的和親對象是個殘疾皇子昆稿,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容