單鏈表節點的添加和刪除



  1. 單鏈表的節點定義

    struct ListNode{
    	int m_nValue;
    	ListNode* m_pNext;
    };
    
  2. 在單鏈表的末尾添加結點

    void AddToTail(LIstNode** pHead,int value) {
    	ListNode* pNew = new ListNode();
    	pNew->m_nValue = value;
    	pNew->m_pNext = NULL;
    
    	if(*pHead == NULL)
    		*pHead = pNew;
    	else
    	{
    		ListNode* pNode = *pHead;
    		while(pNode->m_pNext != NULL)
    		pNode=pNode->m_pNext;
    		pNode->m_pNext = pNew;
    	}
    }
    
  3. 在單鏈表中找到第一個含有某個值的結點並刪除

    void RemoveNode(ListNode** pHead,int value) {
    	if(pHead == NULL || *pHead == NULL)
    		return;
    	//定義一個ListNode指針,用於釋放要刪除的結點
    	ListNode* pToBeDeleted = NULL;  
    	if((*pHead)->m_nValue == value)
    	{
    		pToBeDeleted = *pHead;
    		*pHead = *pHead->m_pNext;
    	}
    	else
    	{
    		// 定義一個臨時的指針,用於遍歷鏈表以找到要刪除的結點(如果存在的話)的前一個結點
    		ListNode* pNode = *pHead;
    		while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
    			pNode = pNode->m_pNext;
    		if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value)
    		{
    			pToBeDeleted = pNode->m_pNext;
    			pNode->m_pNext = pNode->m_pNext->m_pNext;
    		}
    		if(pToBeDeleted != NULL)
    		{
    			delete pToBeDeleted;
    			pToBeDeleted = NULL;
    		}
    	}
    }
    

重點問題:

  • 為什么在添加和刪除函數參數中要用二級指針?
     首先要說的是,函數的參數在傳遞的過程中,傳遞的是實參的一個拷貝。在搜索別人的解釋的過程中,也有人反復強調的另一點是:指針也是有地址的。ok,那么如果函數的參數是一級指針ListNode* pHead,那么函數中使用的pHead是什么?答案是,指向頭結點的指針的副本,也就是另一個指向頭結點的指針。
     
     好了,也就是說接下來在函數中所有的操作都是從這個臨時的pHead開始的。從我們的函數名來看,AddToTail也就是從尾部插入,那這么看來,我只是從尾部插入新的結點,看起來並不影響頭指針。
     那么問題來了,函數中的第七行的判斷,如果頭指針為空,也就是鏈表為空的時候,如果要新插入結點,那么從函數看來我們會改變頭指針pHead另其指向新結點。但是! 前邊我們說了,這個pHead只是函數中的一個 臨時變量,這個指針本身的地址不同於函數外實參指針的地址,而它雖然指向了新結點,但函數外本身傳入的頭指針仍然為 NULL!

     同理,在刪除結點的時候,如果要刪除的結點即第一個結點,使用一級指針也會出錯,此時會導致原頭指針指向的鏈表為空。最后是一個網上借來的圖:出自使用雙重指針實現鏈表結點的插入與刪除

     

    enter description here

     

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM