在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)时间内删除链表节点的关键在于通过重新连接链表中的指针来完成删除。当我们要删除节点i时,可以先将其下一个节点j的值复制到i,然后让i的next指针指向j的下一个节点,最后删除j。这个过程分为以下三种情况: ...
在给定的题目中,我们需要解决的是如何删除一个已排序链表中的重复节点。这个问题是LeetCode中的一个经典算法问题,涉及到链表操作和迭代。下面将详细解释这个问题的解决方案。 首先,我们要明确链表的基本结构。...
以上代码中,`deleteNode`方法实现了链表节点的删除功能。首先检查链表是否为空,然后遍历链表找到目标节点的前一个节点,最后更新前一个节点的`next`指针。 ### 4. 时间和空间复杂度 链表删除操作的时间复杂度...
源代码实现这些操作时,通常会定义一个链表节点结构体,包含数据和指针成员,以及一个链表类或结构体,包含头节点、尾节点和各种操作方法。例如,在C++中,可以创建如下结构: ```cpp struct ListNode { int val; ...
题一:在O(1)时间内删除链表节点。给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点。 解题思路一:先把i的下一个节点j的内容复制到i,然后把i的指针指向节点j的下一个节点。此时再删除节点j...
在链表中删除一个节点通常涉及三个步骤:获取待删除节点的前一个节点、更新前一个节点的next指针以跳过待删除节点、然后释放待删除节点的内存。然而,这道题目有一个特殊之处——给定的只是待删除节点本身,而没有它...
- 插入排序的思想应用在链表上,可以逐个将链表节点按照顺序插入到已排序的链表中。 4. **K个一组翻转链表** (问题25) - 需要定义变量,计数,判断是否有k个节点可以翻转。 - 如果存在k个节点,利用头插法翻转这...
而双向链表的插入操作通常在O(1)时间内完成,如果已知前驱或后继节点,因为只需要调整几个指针即可。但如果需要查找特定位置的节点,仍然可能需要O(n)的时间。 在实际应用中,选择单向链表还是双向链表取决于具体...
这样可以高效地完成链表的分拆,时间复杂度为 O(n),其中 n 为链表中节点的数量。 - **应用场景**: 这种分拆链表的方法在处理大量数据排序、过滤等场景时非常有用。例如,在搜索引擎中,可以根据关键字对搜索结果...
链表的优点是可以动态地增减节点,插入和删除节点的时间复杂度是O(1),但是访问第n个节点的时间复杂度是O(n)。 链表的概念: * 头指针:链表的头指针是非常重要的参数,因为对链表的输出和查找都要从链表的头开始...
`linklist.c`可能包含了上述的插入、删除、显示和逆序等函数的实现,而`struct.c`则定义了链表节点的结构。 链表作为一种基础的数据结构,广泛应用于各种算法和数据结构设计中,如栈、队列、哈希表和图等。熟练掌握...
链表删除操作的时间复杂度通常为O(n),因为在最坏的情况下,我们可能需要遍历整个链表来找到目标节点。空间复杂度为O(1),因为仅需几个额外的指针来辅助操作。 在实际编程中,为了提高代码的可读性和可维护性,通常...
- 然而,查找操作在链表中的效率较低,因为必须从头开始遍历,时间复杂度为O(n)。 7. **ListTest** "ListTest"可能是用于测试链表操作的代码文件。它可能包含了创建、插入、删除、遍历链表等函数的实现,以及一些...
在这个实现中,`ListNode`类定义了链表节点,`mergeTwoLists`函数接收两个链表的头节点,返回合并后的新链表头节点。这个函数遵循了上述逻辑,首先创建一个虚拟头节点,然后通过比较两个链表节点的值进行合并。当...
在 C++ 中,通常使用结构体来表示链表节点,如下所示: ```cpp struct ListNode { int val; ListNode *next; ListNode() : val(0), next(nullptr) {} ListNode(int x) : val(x), next(nullptr) {} ListNode...
链表的插入和删除操作时间复杂度为O(1),但访问特定位置的元素可能需要线性时间,这取决于元素的位置。 通过阅读和理解这个示例程序,你可以加深对C语言链表操作的理解,这对于进一步学习高级数据结构如栈、队列、...
插入操作的时间复杂度为O(1),因为它不依赖于链表的大小,只与找到插入位置所需的时间有关。 3. **链表的删除**:删除节点同样需要找到待删除节点,然后修改其前一个节点的指针指向删除节点的后继节点。如果删除的...
同时,由于双向链表的特性,插入和删除操作的时间复杂度通常为O(1),因为不需要遍历整个链表来找到插入或删除的位置。 双链表在许多实际应用中都有所体现,如实现LRU缓存策略、表示复杂的数据关系等。理解和熟练...
在C语言中,链表节点(或称为结点)可以这样定义: ```c typedef struct Node { int data; // 数据域 struct Node* next; // 指向下一个节点的指针 struct Node* prev; // 双向链表时,指向前一个节点的指针 }...