ソードフィンガーオファー質問18-リンクリストのノードを削除します

トピック1:O(1)時間でリンクリストノードを削除する

タイトル:単一リンクリストのヘッドポインターとノードポインターを指定して、O(1)時間でノードを削除する関数を定義します。
リンクリストのノードと関数は次のように定義されます。

struct ListNode 
{
     
      	
	int   m_nValue; 	
	ListNode*	m_pNext; 
} ```

単一リンクリスト内のノードを削除するには、従来の方法では、最初のノードから開始し、次のノードに進んで、削除する必要のあるノードのノードが見つかるまで判断を下します。

次の図に示すように、
ここに画像の説明を挿入
ノードaから開始して順番にトラバースし、ノードhが削除するノードiを指していることを確認します。したがって、ノードhのm_pNextをijの次のノードに向けます。調整後、ノードiとリストが切断されていないことを確認する
もちろん、ノードを削除する場合は、次のノードのコンテンツをこのノードに上書きしてから、後続のノードを切断すると、ノードが削除されます。
コードは以下の通りであります:

void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
{
    
    
	if(!pListHead || !pToBeDeleted)
		return;
	//删除的节点不是尾节点
	if(pToBeDeleted->next!=nullptr)
	{
    
    
		ListNode* pNext=pToBeDeleted->m_pNext;
		pToBeDeleted->m_nValue=pNext->m_nValue;
		pToBeDeleted->m_pNext=pNext->m_pNext;
		delete pNext;
		pNext=nullptr;
	}
	//链表只有一个节点,删除头节点(也是尾节点)
	else if(*pListHead=pToBeDeleted)
	{
    
    
		delete pToBeDeleted;
		pToBeDeleted=nullptr;
		*pListHead=nullptr;
	}
	//链表中有多个节点,删除尾节点
	else
	{
    
    
		ListNode* pNode=*pListHead;
		while(pNode->m_pNext!=pToBeDeleted)
			pNode=pNode->m_pNext;
			
		pNode->m_pNext=nullptr;
		delete pToBeDeleted;
		pToBeDeleted=nullptr;
	}
}

上記のコードの場合、次のノードの値はO(1)時間で先頭に上書きできますが、それでも順次検索する必要があるため、時間計算量はO(n)です。したがって、合計平均時間計算量は[(n-1)* O(1)+ O(n)] / nであり、結果は依然としてO(1)です。

トピック2:リンクリスト内の重複ノードを削除する

トピック:ソートされたリンクリスト内の重複ノードを削除するにはどうすればよいですか?たとえば、グラフ内の繰り返されるノードを削除すると、リンクリストは図のようになります。
ここに画像の説明を挿入

次に、リンクリスト全体を最初からトラバースします。現在のノードの値が次のノードの値と同じである場合、重複するノードを削除できます。削除後のリンクリストが引き続き接続されていることを確認するには、現在のノードの前のノードを、現在の値よりも大きい値のノードに接続する必要があります。pPreNodeが、複製されていない次のノードに常に接続されていることを確認する必要があります。
コードは次のとおりです。

void DelateDuplication(List** pHead)
{
    
    
	if(pHead==nullptr || *pHead==nullptr)
	return;
	
	ListNode* pPreNode=nullptr;
	ListNode* pNode=*pHead;
	while(pNode!=nullptr)
	{
    
    
		ListNode* pNext=pNode->m_pNext;
		bool needDeleted=false;
		if(pNext!=nullptr && pNext->m_nValue==pNode->m_nValue)
		needDelete=true;
		
		if(!needDelete)
		{
    
    
			pPreNode=pNode;
			pNode=pNode->m_pNext;
		}
		else
		{
    
    
			int value=pNode->m_nValue;
			ListNode* pToBeDel=pNode;
			while(pToBeDel!=nullptr && pToBeDel->m_nValue==value)
			{
    
    
				pNext=pToBeDel->m_pNext;
				
				delete pToBeDel;
				pToBeDel=nullptr;
				
				pToBeDel=pNext;
			}
			if(pPreNode==nullptr)
				*pHead=pNext;
			else
				pPreNode->m_pNext=pNext;
				pNode=pNext;
		}
	}
}

おすすめ

転載: blog.csdn.net/rjszz1314/article/details/104188191