鏈表節點的插入和刪除

插入結點

數組在內存中是順序存儲的,要在數組中插入一個數據就變得頗為麻煩。這就像是在一排麻將中插入一個牌,必須把后面的牌全部依次順移。然而,鏈表中各結點的關系是由指針決定的,所以在鏈表中插入結點要顯得方便一些。這就像是把一條鏈子先一分為二,然后用一個環節再把它們連接起來。如下圖所示。

下面我們先對插入結點這個功能具體分析一下:

  1. 我們必須知道對哪個鏈表進行操作,所以表頭指針head是必須知道的。
  2. 為了確定插入位置,插入位置前的結點指針pGuard是必須是知道的。
  3. 用一個newnode指針來接受新建的結點。
  4. 如果要插入的位置是表頭,由于操作的是表頭指針而不是一個結點,所以要特殊處理。
  5. 在插入結點的過程中,始終要保持所有的結點都在我們的控制范圍內,保證鏈表的完整性。為了達到這一點,我們采用先連后斷的方式:先把新結點和它的后繼結點連接,再把插入位置之前的結點與后繼結點斷開,并與新結點連接。如下圖9.6.3所示。

做完了分析,我們可以開始編寫插入函數了。為了簡單起見,我們規定新結點插入位置為數據是關鍵字的結點之后,這樣就可以使用剛才編寫好的search函數了。如果該結點不存在,則插入在表頭。則插入函數如下:


void insert(node * &head,char keyWord,char newdata)//keyWord是查找關鍵字符
{
    node *newnode=new node;//新建結點
    newnode->data=newdata;//newdata是新結點的數據
    node *pGuard=search(head,keyWord);//pGuard是插入位置前的結點指針
    if (head==NULL || pGuard==NULL)//如果鏈表沒有結點或找不到關鍵字結點
    {//則插入表頭位置
        newnode->next=head;//先連
        head=newnode;//后斷
    }
    else//否則
    {//插入在pGuard之后
        newnode->next=pGuard->next;//先連
        pGuard->next=newnode;//后斷
    }
}

刪除結點

與插入數據類似,數組為了保持其順序存儲的特性,在刪除某個數據時,其后的數據都要依次前移。而鏈表中結點的刪除仍然只要對結點周圍小范圍的操作就可以了,不必去修改其他的結點。仍然我們先要來具體分析刪除結點這個功能:

  1. 我們必須知道對哪個鏈表進行操作,所以表頭指針head是必須知道的。
  2. 一般來說,待刪除的結點是由結點的數據確定的。然而我們還要操作待刪除結點之前的結點(或指針),以連接前后兩段鏈表。之前所寫的search函數只能找到待刪除的結點,卻無法找到這個結點的前趨結點。所以,我們只好放棄search函數,另起爐灶。
  3. 令pGuard指針為待刪除結點的前趨結點指針。
  4. 由于要對待刪除結點作內存釋放,需要有一個指針p指向待刪除結點。
  5. 如果待刪除結點為頭結點,則我們要操作表頭head,作為特殊情況處理。
  6. 在刪除結點的過程中,仍然要始終保持所有的結點都在我們的控制范圍內,保證鏈表的完整性。為了達到這一點,我們還是采用先連后斷的方式:先把待刪除結點的前趨結點和它的后繼結點連接,再把待刪除結點與它的后繼結點斷開,并釋放其空間。如下圖9.6.4所示。
  7. 如果鏈表沒有結點或找不到待刪除結點,則給出提示信息。

由于delete是C++中的保留字,我們無法用它作為函數名,所以只好用Delete代替(C++是大小寫敏感的,Delete和delete是不同的)。都準備好了,我們就可以開始寫函數了:


void Delete(node * &head,char keyWord)//可能要操作表頭指針,所以head是引用
{
    if (head!=NULL)//如果鏈表沒有結點,就直接輸出提示
    {
        node *p;
        node *pGuard=head;//初始化pGuard指針
        if (head->data==keyWord)//如果頭結點數據符合關鍵字
        {
            p=head;//頭結點是待刪除結點
            head=head->next;//先連
            delete p;//后斷
            cout <<"The deleted node is " <<keyWord <<endl;
            return;//結束函數運行
        }
        else//否則
        {
            while (pGuard->next!=NULL)//當pGuard沒有達到表尾
            {
                if (pGuard->next->data==keyWord)//如果pGuard后繼結點數據符合關鍵字
                {
                    p=pGuard->next;//pGuard后繼結點是待刪除結點
                    pGuard->next=p->next;//先連
                    delete p;//后斷
                    cout <<"The deleted node is " <<keyWord <<endl;
                    return;//結束函數運行
                }
                pGuard=pGuard->next;//pGuard指針向后移動
            }
        }
    }
    cout <<"The keyword node is not found or the link list is empty!" <<endl;//輸出提示信息
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結點至多有m個孩子。 除根結點和葉子結點外,其它每個結點至少有m...
    文檔隨手記閱讀 13,355評論 0 25
  • 課程介紹 先修課:概率統計,程序設計實習,集合論與圖論 后續課:算法分析與設計,編譯原理,操作系統,數據庫概論,人...
    ShellyWhen閱讀 2,362評論 0 3
  • 大學的時候不好好學習,老師在講臺上講課,自己在以為老師看不到的座位看小說,現在用到了老師講的知識,只能自己看書查資...
    和玨貓閱讀 1,484評論 1 3
  • 本文來自本人著作《趣學數據結構》 鏈表是線性表的鏈式存儲方式,邏輯上相鄰的數據在計算機內的存儲位置不一定相鄰,那么...
    rainchxy閱讀 3,793評論 6 20
  • 感覺自己盯著手機屏幕都發呆了一會兒了,就是沒有想到該寫什么。昨天和小伙伴打車回去,司機是之前被小伙伴營銷過的目標客...
    聞舒閱讀 177評論 0 0