Pregunta 18 de oferta de Sword Finger: Eliminar el nodo de la lista vinculada

Tema 1: Eliminar el nodo de la lista vinculada en el tiempo O (1)

Título: Dado el puntero principal y un puntero de nodo de una lista enlazada individualmente, defina una función para eliminar el nodo en el tiempo O (1). El
nodo y la función de la lista enlazada se definen de la siguiente manera:

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

Para eliminar un nodo en una lista enlazada individualmente, el método convencional es comenzar desde el primer nodo y pasar al siguiente nodo para hacer juicios hasta que se encuentre el nodo del nodo que necesita ser eliminado.

Como se muestra en la siguiente figura:
Inserte la descripción de la imagen aquí
puede comenzar desde el nodo ay atravesar secuencialmente, encontrar que el nodo h apunta al nodo i para ser eliminado, entonces apunte m_pNext del nodo h al siguiente nodo de ij. Después del ajuste, elimine de manera segura el nodo i y asegúrese de que la lista no sea Desconectar
Por supuesto, si desea eliminar un nodo, hay otras formas, tales como: sobrescribir el contenido del siguiente nodo en este nodo y luego desconectar los nodos subsiguientes, luego el nodo se elimina. El
código es el siguiente:

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;
	}
}

Para el código anterior, el valor del siguiente nodo se puede sobrescribir al frente en el tiempo O (1), pero aún tenemos que buscar secuencialmente, por lo que la complejidad del tiempo es O (n). Entonces, la complejidad de tiempo promedio total es [(n-1) * O (1) + O (n)] / n, el resultado sigue siendo O (1)

Tema 2: Eliminar nodos duplicados en la lista vinculada

Tema: ¿Cómo eliminar nodos duplicados en una lista vinculada ordenada? Por ejemplo, después de eliminar los nodos repetidos en el gráfico, la lista vinculada es como se muestra en la figura
Inserte la descripción de la imagen aquí

Luego recorra toda la lista vinculada desde el principio. Si el valor del nodo actual es el mismo que el valor del siguiente nodo, entonces el nodo duplicado puede ser eliminado. Para garantizar que la lista vinculada después de la eliminación siga conectada, el nodo anterior del nodo actual debe estar conectado al nodo cuyo valor es mayor que el valor actual. Necesitamos asegurarnos de que pPreNode esté siempre conectado al siguiente nodo que no esté duplicado. El
código es el siguiente:

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;
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/rjszz1314/article/details/104188191
Recomendado
Clasificación