數(shù)據(jù)結(jié)構(gòu) ——基于鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的線性表

鏈?zhǔn)酱鎯?chǔ)的定義

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

鏈?zhǔn)酱鎯?chǔ)的邏輯結(jié)構(gòu)
基于鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)的線性表中,每個(gè)節(jié)點(diǎn)都包含數(shù)據(jù)域和指針域。數(shù)據(jù)域用于存儲(chǔ)數(shù)據(jù)元素本身,指針域用于存儲(chǔ)相鄰節(jié)點(diǎn)的地址。

image.png

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

  • 頭指針:
    一個(gè)普通的指針,它的特點(diǎn)是永遠(yuǎn)指向鏈表第一個(gè)節(jié)點(diǎn)的位置。很明顯,頭指針用于指明鏈表的位置,便于后期找到鏈表并使用表中的數(shù)據(jù);
  • 節(jié)點(diǎn):
    鏈表中的節(jié)點(diǎn)又細(xì)分為頭節(jié)點(diǎn)、首元節(jié)點(diǎn)和其他節(jié)點(diǎn):
    頭節(jié)點(diǎn):
    其實(shí)就是一個(gè)不存任何數(shù)據(jù)的空節(jié)點(diǎn),通常作為鏈表的第一個(gè)節(jié)點(diǎn)。對(duì)于鏈表來(lái)說(shuō),頭節(jié)點(diǎn)不是必須的,它的作用只是為了方便解決某些實(shí)際問(wèn)題;
完整的鏈表示意圖

線性表的基本操作方式

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

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

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

  • 即鏈表的新節(jié)點(diǎn)的next指針會(huì)指向null,然后操作LinkedList對(duì)象的頭指針指向新的節(jié)點(diǎn),完成鏈表頭節(jié)點(diǎn)插入新節(jié)點(diǎn)動(dòng)作。

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

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

在末端插入元素操作

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

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

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

插入新節(jié)點(diǎn)操作需遍歷到第i-1個(gè)節(jié)點(diǎn),插入前需要將一個(gè)臨時(shí)指針副本偏移到指定索引的位置,第i-1個(gè)位置的節(jié)點(diǎn)的next指針需要指向新的節(jié)點(diǎn),新的節(jié)點(diǎn)的next指針需要指向原來(lái)第i-1個(gè)位置的節(jié)點(diǎn)的next指針

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

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

    for(int j = 0;j<i;j++)      //遍歷到第i-1個(gè)節(jié)點(diǎn),因?yàn)椴迦肭靶枰獙⒁粋€(gè)臨時(shí)指針副本偏移到指定索引的位置,需要注意的
    {
        currentNode = currentNode->next;
    }
    Node *newNode = new Node;
    if(newNode == NULL)
    {
        return false;
    }
    newNode->data = pNode->data;            //賦值
    newNode->next = currentNode->next;      //原來(lái)currentNode的下一個(gè)節(jié)點(diǎn)變成了newNode的下一個(gè)節(jié)點(diǎn)
    currentNode->next = newNode;            //再把newNode成為urrentNode的下一個(gè)節(jié)點(diǎn)
    m_iLength++;
    return true;
}

鏈表中刪除節(jié)點(diǎn)

此時(shí)與插入節(jié)點(diǎn)操作不同的最大不同的是遍歷到第i個(gè)節(jié)點(diǎn),因?yàn)閷?duì)于單向鏈表來(lái)說(shuō),一但我們的遍歷的指針位于第i個(gè)節(jié)點(diǎn)時(shí)已經(jīng)無(wú)法返回到位于i-1位置的節(jié)點(diǎn),此時(shí)我們將位于第i個(gè)位置的節(jié)點(diǎn)執(zhí)行delete操作,那么第i-1個(gè)位置的節(jié)點(diǎn)與第k+1個(gè)位置的節(jié)點(diǎn)本應(yīng)要建立的鏈接關(guān)系已經(jīng)無(wú)法建立,那么從第k+1個(gè)位置的節(jié)點(diǎn)算起的部分與鏈表就“斷鏈”,造成鏈表內(nèi)存泄漏。

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

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

清空鏈表操作

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

//清空鏈表操作
void LinkList::ClearList()
{
    //刪除節(jié)點(diǎn)
   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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容