在O(1)时间删除链表的节点
题目:
给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点,
我们要删除一个节点i,先把i的下一个节点j的内容复制到i,然后把i 的指针指向节点j的下一个节点。此时再删除节点
j,其效果就是把节点i给删除了 。
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
void deleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
{
if(!pListHead||!pToBeDeleted)
return ;
//删除的节点不是尾节点
if(pToBeDeleted->m_pNext!=NULL)
{
ListNode* pNext=pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue=pNext->m_nValue;
pToBeDeleted->m_pNext=pNext->m_pNext;
delete pNext;
pNext=NULL;
}
//链表只有一个节点,删除头节点(也是尾节点)
else if(*pListHead==pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted=NULL;
*pListHead=NULL;
}
//链表中有多个节点,删除尾节点
else
{
ListNode* pNode=*pListHead;
while(pNode->m_pNext!=pToBeDeleted)
{
pNode= pNode->m_pNext;
}
pNode->m_pNext=NULL;
delete pToBeDeleted;
pToBeDeleted =NULL;
}
}
int main()
{
int nodeNum,deleted;
while(scanf("%d %d",&nodeNum,&deleted)!=EOF)
{
int data;
scanf("%d",&data);
ListNode* listHead=(ListNode*)malloc((sizeof(ListNode)));
if(listHead==NULL)
exit(EXIT_FAILURE);
listHead->m_nValue=data;
listHead->m_pNext=NULL;
ListNode* pCur=listHead;
ListNode* pDeleted = pCur;
int curNum=nodeNum;
for(int i=0;i<nodeNum-1;i++)
{
int nodeData;
scanf("%d",&nodeData);
ListNode* newNode=(ListNode*)malloc(sizeof(ListNode));
if(newNode==NULL)
exit(EXIT_FAILURE);
newNode->m_nValue=nodeData;
newNode->m_pNext=NULL;
pCur->m_pNext=newNode;
pCur=pCur->m_pNext;
if(pCur->m_nValue==deleted)
{
pDeleted=pCur;
curNum--;
}
}
deleteNode(&listHead,pDeleted);
ListNode* pNode=listHead;
for(int i=0;i<curNum;i++)
{
printf("%d",pNode->m_nValue);
pNode=pNode->m_pNext;
}
}
return 0;
}
结果:

分享到:
相关推荐
在链表中删除结点是编程中的一种常见操作,但是如何在O(1)时间复杂度中删除结点却是一种挑战性的任务。今天,我们将讨论一种可行的解决方案,并提供完整的代码实现。 首先,让我们来看一下链表结点的定义: ```c ...
在O(1)时间内删除链表节点的关键在于通过重新连接链表中的指针来完成删除。当我们要删除节点i时,可以先将其下一个节点j的值复制到i,然后让i的next指针指向j的下一个节点,最后删除j。这个过程分为以下三种情况: ...
/* 链表节点的定义 */ static class Node { int data; Node next; Node(int d) { data = d; next = null; } } /* 删除链表末尾节点的函数 */ public void deleteLastNode() { // 如果链表为空,直接...
在给定的题目中,我们需要解决的是如何删除一个已排序链表中的重复节点。这个问题是LeetCode中的一个经典算法问题,涉及到链表操作和迭代。下面将详细解释这个问题的解决方案。 首先,我们要明确链表的基本结构。...
这个操作的效率受到链表长度的影响,最坏情况下的时间复杂度是O(n),其中n是链表的长度。 此外,还有特殊情况需要考虑,比如双向链表。在双向链表中,每个节点不仅包含指向下一个节点的指针,还包含指向前一个节点...
以上代码中,`deleteNode`方法实现了链表节点的删除功能。首先检查链表是否为空,然后遍历链表找到目标节点的前一个节点,最后更新前一个节点的`next`指针。 ### 4. 时间和空间复杂度 链表删除操作的时间复杂度...
同时,要注意避免内存泄露,确保在删除原链表节点时释放了节点所占用的内存资源。 在进行链表操作时,C语言没有像一些高级语言那样的垃圾回收机制,因此需要开发者手动管理内存。这意味着在进行节点删除或链表合并...
源代码实现这些操作时,通常会定义一个链表节点结构体,包含数据和指针成员,以及一个链表类或结构体,包含头节点、尾节点和各种操作方法。例如,在C++中,可以创建如下结构: ```cpp struct ListNode { int val; ...
题一:在O(1)时间内删除链表节点。给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。 解题思路一:先把i的下一个节点j的内容复制到i,然后把i的指针指向节点j的下一个节点。此时再删除节点j...
在链表中删除一个节点通常涉及三个步骤:获取待删除节点的前一个节点、更新前一个节点的next指针以跳过待删除节点、然后释放待删除节点的内存。然而,这道题目有一个特殊之处——给定的只是待删除节点本身,而没有它...
- 插入排序的思想应用在链表上,可以逐个将链表节点按照顺序插入到已排序的链表中。 4. **K个一组翻转链表** (问题25) - 需要定义变量,计数,判断是否有k个节点可以翻转。 - 如果存在k个节点,利用头插法翻转这...
5. 链表插入操作的时间复杂度分析,通常为O(n),但相较于数组更为灵活。 6. 代码实现的具体方法,包括节点类和链表类的定义,以及插入操作的函数实现。 通过以上知识的掌握,我们可以更高效地运用链表解决实际编程...
而双向链表的插入操作通常在O(1)时间内完成,如果已知前驱或后继节点,因为只需要调整几个指针即可。但如果需要查找特定位置的节点,仍然可能需要O(n)的时间。 在实际应用中,选择单向链表还是双向链表取决于具体...
这样可以高效地完成链表的分拆,时间复杂度为 O(n),其中 n 为链表中节点的数量。 - **应用场景**: 这种分拆链表的方法在处理大量数据排序、过滤等场景时非常有用。例如,在搜索引擎中,可以根据关键字对搜索结果...
链表的优点是可以动态地增减节点,插入和删除节点的时间复杂度是O(1),但是访问第n个节点的时间复杂度是O(n)。 链表的概念: * 头指针:链表的头指针是非常重要的参数,因为对链表的输出和查找都要从链表的头开始...
C++版本中,首先定义了链表节点的数据结构ListNode,然后在Solution类中实现deleteDuplicates函数。该函数首先处理链表为空的情况,然后通过双指针法遍历并修改链表指针,最终返回处理后的链表头节点。Python版本中...
`linklist.c`可能包含了上述的插入、删除、显示和逆序等函数的实现,而`struct.c`则定义了链表节点的结构。 链表作为一种基础的数据结构,广泛应用于各种算法和数据结构设计中,如栈、队列、哈希表和图等。熟练掌握...
链表删除操作的时间复杂度通常为O(n),因为在最坏的情况下,我们可能需要遍历整个链表来找到目标节点。空间复杂度为O(1),因为仅需几个额外的指针来辅助操作。 在实际编程中,为了提高代码的可读性和可维护性,通常...
- 然而,查找操作在链表中的效率较低,因为必须从头开始遍历,时间复杂度为O(n)。 7. **ListTest** "ListTest"可能是用于测试链表操作的代码文件。它可能包含了创建、插入、删除、遍历链表等函数的实现,以及一些...
在这个实现中,`ListNode`类定义了链表节点,`mergeTwoLists`函数接收两个链表的头节点,返回合并后的新链表头节点。这个函数遵循了上述逻辑,首先创建一个虚拟头节点,然后通过比较两个链表节点的值进行合并。当...