1. 程式人生 > >使用雙重指標實現連結串列結點的插入與刪除

使用雙重指標實現連結串列結點的插入與刪除

單鏈表結點的插入和刪除是資料結構中很基本的操作。如果單鏈錶帶有頭結點,那麼可以把頭結點指標傳遞給插入和刪除函式;可如果對無頭結點的單鏈表進行上述操作,僅傳遞頭指標(指向第一個結點的指標),在插入或刪除操作改變連結串列頭指標時,將會有些問題。
下面我們通過一個例項說明這個問題。

//單鏈表結點定義
struct ListNode
{
    int val;
    ListNode* next;
    ListNode(int value):val(value), next(NULL){}
};

採用“尾插法”向連結串列中插入結點,如果用以下程式碼實現:

//insert.cpp version_1
void add2Tail(ListNode* pHead, int value) { ListNode* pNew = new ListNode(value); if(!pHead) pHead = pNew; //? else { ListNode* pNode = pHead; while(pNode->next) pNode = pNode->next; pNode->next = pNew; } }

上述程式碼中,給add2Tail函式傳遞的是指向連結串列第一個結點的指標。可是這段程式碼第四行有個很嚴重的問題,由於當原連結串列為空,插入新結點時會改變“頭指標”pHead,但這種改變僅僅改動的是函式內部的區域性變臉pHead,原連結串列“頭指標”(實參)實際上仍為NULL。具體可參照下面的圖示:

連結串列指標
tips:上圖中,當函式形參為指向連結串列第一個結點的指標時,”傳值“方式傳遞的是地址100;而形參如果為指向頭指標的指標,傳遞的是地址200。

因此我們要對這段程式碼做一些改動,給add2Tail傳遞指向“頭指標”的指標,這樣便可達到當pHead==NULL時,插入新結點後也可改動外部的pHead。程式碼如下:

//insert.cpp version_2
void add2Tail(ListNode** pHead, int value)
{
    ListNode* pNew = new ListNode(value);
    if(!*pHead) *pHead = pNew;    //原連結串列為NULL
else { ListNode* pNode = *pHead; while(pNode->next) pNode = pNode->next; pNode->next = pNew; } }

同理,刪除單鏈表中第一個含有某特定值的結點時,如果第一個結點就是待刪除結點的話,這將改變頭指標,因此也要給刪除函式傳遞指向頭指標的指標,程式碼如下:

void removeNode(ListNode** pHead, int value)
{
    if(!pHead || !*pHead) return;
    ListNode *p2BeRemoved = NULL;
    if((*pHead)->val == value)    //第一個結點為待刪除物件
    {
        p2BeRemoved = *pHead;
        *pHead = (*pHead)->next;
    }
    else    
    {
        ListNode* pNode = *pHead;
        while(pNode->next && pNode->next->val != value) pNode = pNode->next;

        if(pNode->next && pNode->next->val == value)
        {
            p2BeRemoved = pNode->next;
            pNode->next = pNode->next->next;
        }
    }

    if(p2BeRemoved)
    {
        delete p2BeRemoved;    
        p2BeRemoved = NULL;   //刪除指標後,最後將其賦與NULL值,防止野指標
    }
}

相關推薦

使用雙重指標實現連結串列結點插入刪除

單鏈表結點的插入和刪除是資料結構中很基本的操作。如果單鏈錶帶有頭結點,那麼可以把頭結點指標傳遞給插入和刪除函式;可如果對無頭結點的單鏈表進行上述操作,僅傳遞頭指標(指向第一個結點的指標),在插入或刪除操作改變連結串列頭指標時,將會有些問題。 下面我們通過一個例

C語言連結串列節點插入刪除

線性表操作 順序表是我們資料結構中的基本儲存形式,現在給定一個順序表,有如下操作: Insert X Y:在順序表中X位置插入Y元素,遍歷輸出當前順序表的所有元素。 Delete X:刪除順序表中的X元素,如果有多個X元素,只刪除第一個X,遍歷輸出當前順序的所有

雙向連結串列插入刪除節點

#include <stdio.h> #include <malloc.h> typedef struct linknode//定義雙向連結串列 { int data; linknode *prior,*next; } Node,*

【資料結構】順序表、單鏈表、迴圈連結串列插入刪除

寫在前面的 順序表 插入 刪除 定位 單鏈表 插入 刪除 總結 寫在前面的        在複習資料結構的過程中對於連結串列的操作總是容易忘記,時不時的就不知道具體的該怎麼

線性連結串列插入刪除

程式碼功能:實現連結串列插入與刪除的基本功能 線性表插入與刪除操作 Input 第一行給出線性表內現有資料元素的數目N,1<=N<=10;第二行給出N個整數:a1、a2、a3…aN,

用陣列來實現連結串列插入查詢刪除功能

假設有100名員工,他們分別在10家公司中,現在要模擬他們的入職(插入)、資訊查詢(查詢)、離職(刪除)等管理操作行為,用陣列來代替連結串列實現,具體程式碼如下:#include "stdafx.h" #include <stdlib.h> #define EM

連結串列插入刪除操作詳解(C語言實現+詳解註釋)

連結串列的基本操作中,連結串列結點的插入和刪除相對比較複雜,需根據結點插入位置的不同,使用合理的方法在不破壞原連結串列結構的前提下將其插入到連結串列中。 本節將詳解介紹這兩種操作的具體實現方法,讀者只需牢記實現步驟,即可輕鬆解決這兩大難點。 連結串列中插入結點 連結串列中插入結點,根據插入位置的不同,可

java實現--單向連結串列插入刪除

一、連結串列結構: (物理儲存結構上不連續,邏輯上連續;大小不固定)           概念:  鏈式儲存結構是基於指標實現的。我們把一個數據元素和一個指標稱為結點。        資料域:存數資料元素資訊的域。        指標域:儲存直接後繼位置的域。鏈式儲存結構是用

C語言 連結串列插入刪除

#include <stdio.h>#include <malloc.h>#include "SeqList.h"typedef unsigned int TSeqListNode;typedef struct _tag_SeqList{    int

連結串列插入刪除,顯示,排序

#include <stdio.h> #include <stdlib.h> typedef struct stu{ int value; struct stu *next

雙向連結串列插入刪除圖解

雙向連結串列的插入 第一步:首先找到插入位置,節點 s 將插入到節點 p 之前 第二步:將節點 s 的前驅指向節點 p 的前驅,即 s->prior = p->prior; 第三步:將節點 p 的前驅的後繼指向節點 s 即 p->pr

C++ 單鏈表基本操作分析與實現 連結串列   連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點連結串列中每一個元素稱為結點)組成,結

連結串列   連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表

用結構體實現連結串列的建立、遍歷、結點插入結點刪除連結串列刪除-----帶選單選項

#include <iostream> using namespace std; enum operation{create_List=1,print_List,insert_Node,delete_Node,delete_List,quit};//列舉型別,

資料結構之快慢指標查詢連結串列中間結點

       單鏈表是一種十分常見和應用廣泛的資料結構,也是面試題經常會問到的一個。近期複習單鏈表,就將這個單鏈表常見的考點順便複習了一遍。       面試題:如何最快的獲取單鏈表的中間節點的位置?   &nb

資料結構演算法JavaScript描述讀書筆記(js實現連結串列-迴圈連結串列

迴圈連結串列 迴圈連結串列同單鏈表,只需設定head.next = head就可以實現迴圈連結串列 其它方法不變,但是遍歷方法需要改一下 function display() { var cur = this.head; var str = ''; //如果不設定

資料結構演算法JavaScript描述讀書筆記(js實現連結串列-雙向連結串列

雙向連結串列 雙向連結串列的 remove() 方法比單向連結串列的效率更高,因為不需要再查詢前驅節點了 //建立建構函式建立節點 function Node(element){ this.element = element; this.next = null; th

資料結構演算法JavaScript描述讀書筆記(js實現連結串列-單鏈表)

單鏈表 //建立建構函式建立節點 function Node(element){ this.element = element; this.next = null; } //連結串列的建構函式 function LList(){ this.head = new Node

[LeetCode] Insert into a Cyclic Sorted List 在迴圈有序的連結串列插入結點

  Given a node from a cyclic linked list which is sorted in ascending order, write a function to insert a value into the list such that it remains a

C寫連結串列線性表的建立插入刪除

連結串列 #include <bits/stdc++.h> typedef struct node { int data; struct node *next; } Lnode; Lnode *L; void dele(int pos){ Lnode *p;

【資料結構】帶有尾指標連結串列連結串列實現佇列

前面寫了用動態陣列實現佇列,現在我將用帶有尾指標的連結串列實現佇列。 我們知道佇列需要在兩端進行操作,如果是以普通連結串列進行底層實現的佇列,在入隊時需要找到最後一個節點才能進行新增元素,這樣相當於遍歷一遍連結串列,從而造成巨大的時間浪費。 為了解決這個問題,我們引入了尾