剑指offer面试题18(1)删除链表中的节点

主要思想:把要求删除的节点的下个节点的值赋给待删节点,然后把下一个节点删除。这样时间复杂度是O(1)。之前通过待删除节点和该节点前面的节点,要通过从头节点开始遍历的方式找待删节点前面的节点,时间复杂度是O(n)

知识点:联系面试题5和6,可以看下我的博文

面试题5(基本涵盖下面的知识点1-5) https://blog.csdn.net/qq_34793133/article/details/80590992

面试题6(逆序打印链表)https://blog.csdn.net/qq_34793133/article/details/80571173

1.创建链表(可以同面试题5中尾部添加节点的方式或者本文的CreateNode()和ConnectNode()结合的方式),

2.添加节点,

3.查找节点,

4.删除节点,ToBeDeleteted前面的节点赋nullptr;  delete ToBeDeleteted;   ToBeDeleteted=nullptr

5.正序打印链表,

6.逆序打印链表


本题我写的代码如下:

#include <iostream>
using namespace std;

struct ListNode
{
	ListNode* next;
	int value;
};

ListNode* CreateNode(int n_value)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	node->next = nullptr;
	node->value = n_value;

	return node;
}

void ConnectNode(ListNode* node1, ListNode* node2)
{
	node1->next = node2;
	node2->next = nullptr;
}

void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
//此处pListHead是指向指针的指针,即传指针:形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作
//如果是ListNode* pListHead,相当于传值:形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参),参数的值只能传入,
//下面是有助于理解传值和传指针的简单例子,不懂的同学可以看下,我在本文末尾的注释

{
	if (!pListHead || !pToBeDeleted)
		return;

	// 要删除的结点不是尾结点
	if (pToBeDeleted->next != nullptr)
	{
		ListNode* pNext = pToBeDeleted->next;
		pToBeDeleted->value = pNext->value;
		pToBeDeleted->next = pNext->next;

		delete pNext;
		pNext = nullptr;
	}
	// 链表只有一个结点,删除头结点(也是尾结点),头结点得next指针域也是空
	else if (*pListHead == pToBeDeleted)
	{
		delete pToBeDeleted;
		pToBeDeleted = nullptr;
		*pListHead = nullptr;
	}
	// 链表中有多个结点,删除尾结点
	else
	{
		ListNode* pNode = *pListHead;
		while (pNode->next != pToBeDeleted)
		{
			pNode = pNode->next;
		}

		pNode->next = nullptr;
		delete pToBeDeleted;
		pToBeDeleted = nullptr;
	}
}


void PrintList(ListNode* temp_print)
{
	if (temp_print == nullptr)
		printf("要打印的链表为空,请检查输入链表\n");


	else
	{
		ListNode* temp2 = temp_print;
		while (temp2 != nullptr)
		{
			printf("%d  ", temp2->value);
			temp2 = temp2->next;

		}

		printf("\n");
	}
}

void Test1()
{
	cout << "Test1 链表有多个节点且不做删除" << ": ";
	ListNode* node1 = CreateNode(1);
	ListNode* node2 = CreateNode(2);
	ListNode* node3 = CreateNode(3);
	ListNode* node4 = CreateNode(4);
	ListNode* node5 = CreateNode(5);

	ConnectNode(node1, node2);
	ConnectNode(node2, node3);
	ConnectNode(node3, node4);
	ConnectNode(node4, node5);

	ListNode* pHead = nullptr;
	pHead = node1;

	PrintList(pHead);



}


void Test2()
{
	cout << "Test2 删除中间节点" << ": ";
	ListNode* node1=CreateNode(1);
	ListNode* node2=CreateNode(2);
	ListNode* node3=CreateNode(3);
	ListNode* node4=CreateNode(4);
	ListNode* node5=CreateNode(5);

	ConnectNode(node1, node2);
	ConnectNode(node2, node3);
	ConnectNode(node3, node4);
	ConnectNode(node4, node5);

	ListNode* pHead = nullptr;
	pHead= node1;

	DeleteNode(&pHead, node3);

	PrintList(pHead);

}

void Test3()
{
	cout << "Test3  链表中只有一个节点的情况" << ": ";
	ListNode* node1 = CreateNode(1);

	ListNode* pHead = nullptr;
	pHead = node1;

	DeleteNode(&pHead, node1);

	PrintList(pHead);

}

void Test4()
{
	cout <<"Test4 链表不止一个节点且删除尾节点" << ": ";
	ListNode* node1 = CreateNode(1);
	ListNode* node2 = CreateNode(2);
	ListNode* node3 = CreateNode(3);
	ListNode* node4 = CreateNode(4);
	ListNode* node5 = CreateNode(5);

	ConnectNode(node1, node2);
	ConnectNode(node2, node3);
	ConnectNode(node3, node4);
	ConnectNode(node4, node5);

	ListNode* pHead = nullptr;
	pHead = node1;

	DeleteNode(&pHead, node5);

	PrintList(pHead);

}

int main()
{
	Test1();
	Test2();
	Test3();
	Test4();
	return 0;
}

运行结果


注释:关于形参实参之间传值和传指针的问题

          有时间可以看我的这篇博客:https://blog.csdn.net/qq_34793133/article/details/80819690

           没有时间可以简单看下这个小例子

#include <iostream>
using namespace std;

void fun1(int* a, int*  b)    //传指针,会因为形参的改变而改变对应的会改变实参a,b
{
	//*a--;*b++;
	(*a)--; (*b)++;
}

void fun2(int c, int d)      // //传指针,不会因为形参的改变而改变对应的会改变实参a,b
{
	c--; d++;
}
int main()
{
	int a = 5; int b = 10;
	int c = 5; int d = 10;
	fun1(&a, &b);
	fun2(c, d);


	cout << a << " " << b << endl;    //4 11
	cout << c << " " << d << endl;    //5 10

	return 0;
}

 
 

本文是博主原创文章,未经博主允许不得转载

猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80826553