每日一题(5) - 在O(1)时间删除链表结点

题目来自剑指Offer

题目

每日一题(5) - 在O(1)时间删除链表结点_第1张图片

代码

#include <iostream>
#include <assert.h>
using namespace std;

struct ListNode 
{
	int m_Data;
	struct ListNode* m_pNext;
};
void PrintList(ListNode* pHead);

/*
*pListHead指向第一个结点
pToDeleted指向要删除的结点
*/
void DeleteNode(ListNode** pListHead,ListNode* pToDeleted)
{
	assert(*pListHead != NULL && pToDeleted != NULL);
	ListNode* pCurNode = NULL;
	ListNode* pNextNode = NULL;

	//删除结点为不是尾结点
	if (pToDeleted->m_pNext != NULL)
	{
		pNextNode = pToDeleted->m_pNext;
		pToDeleted->m_Data = pNextNode->m_Data;
		pToDeleted->m_pNext = pNextNode->m_pNext;
		delete pNextNode;
	}
	else if(*pListHead == pToDeleted)//删除结点为链表第一个结点
	{
		delete pToDeleted;
		pToDeleted = NULL;
		*pListHead = NULL;
	}
	else
	{
		//删除结点为链表最后一个结点
		pCurNode = *pListHead;
		while (pCurNode->m_pNext != pToDeleted)
		{
			pCurNode = pCurNode->m_pNext;
		}
		pCurNode->m_pNext = NULL;
		delete pToDeleted;
		pToDeleted = NULL;
	}
}

void DeleteNode(ListNode** pListHead)
{
	assert(*pListHead);
	cout<<"删除第一个结点:"<<endl;
	DeleteNode(pListHead,(*pListHead));//删除第一个结点
	PrintList(*pListHead);

	cout<<"删除第二个结点:"<<endl;
	if ((*pListHead)&&(*pListHead)->m_pNext)
	{
		DeleteNode(pListHead,(*pListHead)->m_pNext);//删除第二个结点
		PrintList(*pListHead);
	}

	//删除结点为链表最后一个结点
	cout<<"删除最后一个结点:"<<endl;
	ListNode* pCurNode = *pListHead;
	while (pCurNode && pCurNode->m_pNext)
	{
		pCurNode = pCurNode->m_pNext;
	}
	if (pCurNode)
	{
		DeleteNode(pListHead,pCurNode);
		PrintList(*pListHead);
	}
}

void CreateListBackword(ListNode*& pHead,int nLen)

{
	assert(pHead == NULL && nLen > 0);
	ListNode* pNewNode = NULL;
	for (int i = 0;i < nLen;i++)
	{
		pNewNode = new ListNode;
		cin>>pNewNode->m_Data;
		pNewNode->m_pNext = NULL;

		if (pHead == NULL)
		{
			pHead = pNewNode;
		}
		else
		{
			pNewNode->m_pNext = pHead;
			pHead = pNewNode;
		}
	}
}


void PrintList(ListNode* pHead)
{
	while (pHead)
	{
		cout<<pHead->m_Data<<" ";
		pHead = pHead->m_pNext;
	}
	cout<<endl;
}

int main()
{
	int nLen = 0;
	struct ListNode* pHead = NULL;
	cout<<"please input node num: ";
	cin >> nLen;
	CreateListBackword(pHead,nLen);
	PrintList(pHead);
	DeleteNode(&pHead);
	system("pause");
	return 1;
}

说明:由于删除位于链表中间位置的结点还是占大多数的,因此该情况应该放在if的第一层,进而减少比较次数。
 

你可能感兴趣的:(每日一题(5) - 在O(1)时间删除链表结点)