在O(1)的时间内删除链表的指定结点

题目:给定单项链表的头指针和一个结点指针,定义一个函数在o(1)的时间删除该结点,链表的定义如下:

struct ListNode{
  int value;

  ListNode* next;

};

函数定义:void DeleteNode(ListNode** PListHead,ListNode* pToBedelete);

如上图所示,想要删除一个单链表的中的某个结点有两种方式:

1、如上图中的( b)所示:要删除i结点,必须从头扫描,扫到h(i的前一个结点),然后让其next值指向j(i的下一个位置),然后就可以删除i了。此方法的复杂度为O(n),因为要删除某个结点必须找到其上一个结点,故需要从头遍历。

2、如上图中的(c)所示:要删除i结点,可以先把i的下一节点的值赋给i结点,然后让i的next值指向下一节点的下一结点,就相当于删除i结点。(注意要保存i->next的这个结点,然后再删除),此算法复杂度为O(1),但是必须要求此要删除结点一定是链表中的结点,且当要删除的结点为最后一个结点时,必须用第一种方法,顺序遍历后找到最后一结点的上一结点,然后删除,但此方法的平均时间复杂度仍然为O(1).

故代码如下:

注意:delete结点后一定要让结点指向nullptr(每次都忘。。。)

 1 //在O(1)的时间删除链表指定的结点
 2 struct ListNode{
 3     int value;
 4     ListNode *next;
 5 };
 6 void DeleteNode(ListNode** pListHead, ListNode *pToBeDelete)
 7 {
 8     if (pListHead == nullptr || *pListHead == nullptr || pToBeDelete == nullptr)
 9         return;
10     if (*pListHead == pToBeDelete&&pToBeDelete->next == nullptr)//若是头节点也是最后一个节点
11     {
12         delete pToBeDelete;
13         pToBeDelete = nullptr;
14         *pListHead = nullptr;
15     }
16     else if (*pListHead != pToBeDelete&&pToBeDelete->next == nullptr)//若是最后一个节点
17     {
18         ListNode* p = *pListHead;
19         while (p->next!=pToBeDelete)
20         {
21             p = p->next;
22         }
23         delete pToBeDelete;
24         pToBeDelete = nullptr;
25         p->next = nullptr;
26     }
27     else{//要删除的节点不是尾节点
28         ListNode* pd = pToBeDelete->next;
29         pToBeDelete->value = pd->value;
30         pToBeDelete->next = pd->next;
31         delete pd;
32         pd = nullptr;
33     }
34 }
时间: 2025-01-08 07:55:58

在O(1)的时间内删除链表的指定结点的相关文章

【编程题目】在 O(1)时间内删除链表结点

60.在 O(1)时间内删除链表结点(链表.算法).题目:给定链表的头指针和一个结点指针,在 O(1)时间删除该结点.链表结点的定义如下:struct ListNode{int m_nKey;ListNode* m_pNext;};函数的声明如下:void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted); 思路:把当前结点的下一个结点的内容复制到当前结点,删除下一结点即可. 注意,链表中只有一个结点时在题目给定的函数声明下无法删除,

链表《4》删除链表中的结点

下图是一个创建好的链表 下面我们需要删除一个结点,例如删除第3个结点 首先定义一个指针p,并且将p指向第二个结点 然后定义一个指针q,将q指向需要删除的结点 将p指向的结点和q指向的结点相连 p->pNext = q->pNext 清空q指向的结点 free(q); q = NULL; 删除后的链表 程序代码: #include <stdio.h> #include <stdlib.h> typedef struct Node//结点结构 { int data;//数据

第六十题(在O(1)时间内删除链表结点)

题目:给定链表的头指针和一个结点指针,在O(1)时间删除该结点. 思路:将待删除节点下一个节点的数据赋给当前节点.删除下一个节点就可以.

在O(1)时间内删除链表节点

题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)的时间删除该节点. struct ListNode { int    m_nValue; ListNode* m_pNext; }; void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted): 算法思路: 一般我们是从头节点开始遍历,知道找到要删除的节点的前面一个节点,但是时间复杂度为O(n) 改进思路:找到要删除的节点pDeleteNode的下一个节点pNext,把

在O(1)时间内删除链表节点(剑指offer_18.1)

解题思路 如果该节点不是尾结点,那么可以直接将下一个节点的值赋给该节点,然后该节点指向下下个节点,再删除下一个节点,时间复杂度为O(1). 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向null,时间复杂度为O(N).综上,如果进行N次操作,那么大约需要操作节点的次数为N-1+N = 2N - 1,其中N-1表示N-1个不是尾结点的每个节点以O(1)时间复杂度操作该节点的总次数,N表示1个尾结点以O(N)的时间复杂度操作节点的总次数.(2N-1)/N ~ 2,因此该算法的平均

在O(1)的时间删除链表结点

题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除节点.链表结点与函数的定义如下: struct ListNode {     int m_nValue;     ListNode* m_pNext; }; void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted); 分析:要删除结点i,先把i的下一个节点j的内容复制给i,然后把i的指针指向结点j的下一个结点.此时再删除结点j,其效果相当于把结点i删除了. 上

O(1)时间删除链表结点

题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点.链表结点与函数的定义如下: typedef struct ListNode { int val; struct ListNode *p_next; }NODE, *PNODE; void delete_node(PNODE *pListHead, PNODE pToDeleted); 一般来说,我们拿到一个删除链表的某个结点的题目,最常规的解法无疑是从链表的头结点开始顺序遍历,依次查找要删除的结点,找到被删除结点的前

面试题18:删除链表节点

18.1 在 O(1) 时间内删除链表节点 <?php header("content-type:text/html;charset=utf-8"); /* * 在 O(1) 时间内删除链表节点. P119 */ class ListNode{ var $val; var $next = NULL; function __construct($x){ $this->val = $x; } } function deleteNode($head,$deleteNode){ i

18 删除链表的节点/重复节点

题目描述:  题目一:在O(1)时间内删除链表节点 :在给定的单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点. //链表定义 struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; 注意:输入提供了要删除节点的指针!! 测试用例: 1)功能测试(从有多个节点的链表中删除中间.头.尾节点:从只有一个节点的链表中删除唯一的节点) 2)特殊输入测试