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

思路:

时间复杂度要求为O(1),已知要删除的节点,可以找到该节点的下一个节点,把下一个节点的相关信息复制到要删除的节点上,删除下一个节点,可以达到题目要求。

注意:删除尾节点时需要遍历一遍,删除头结点时,需要把头结点移到下一个节点。

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

struct Listnode
{
	int _value;
	Listnode* _next;
};
void Init(Listnode*& head)
{
	Listnode* cur =head;
	if(cur==NULL)
	{
		cur=(Listnode*)malloc(sizeof(Listnode));
		cur->_next=NULL;
		cur->_value=0;
	}
	head=cur;
}

void push(Listnode*& head,int value)
{
	Listnode* cur =head;

		while(cur->_next)
		{
			cur=cur->_next;
		}
		Listnode* tmp=NULL;
		tmp=(Listnode*)malloc(sizeof(Listnode));
		tmp->_next=NULL;
		tmp->_value=value;
		cur->_next=tmp;

}
void pop(Listnode* head)
{
	Listnode* cur=head;
	Listnode* prev=NULL;
	while(cur->_next!=NULL)
	{
		prev=cur;
		cur=cur->_next;
	}
	prev->_next=NULL;
	free(cur);
	cur=NULL;
}
void print(Listnode* head)
{
	Listnode* cur=head;
	while(cur)
	{
		printf("%d\n",cur->_value);
		cur=cur->_next;
	}
}
Listnode* Find(Listnode* head,int value)
{
	assert(head);
	Listnode* cur=head;
    while(cur)
	{
		if(cur->_value==value)
		{
			return cur;
		}
		else
		{
			cur=cur->_next;
		}
	}
}
void DeleteNode(Listnode* &head,Listnode* pToBeDeleted)
{
	Listnode* cur=head;
	if(cur==NULL)
	{
		return;
	}
	if(pToBeDeleted==head)
	{
		head=cur->_next;
		free(cur);
		cur=NULL;
		return;
	}
	Listnode* last=pToBeDeleted->_next;
	if(last!=NULL)
	{
		pToBeDeleted->_value=last->_value;
		pToBeDeleted->_next=last->_next;
		free(last);
		last=NULL;
	}
	else    //删除的是尾节点
	{
		Listnode* prev=NULL;
		while(cur->_next!=NULL)
		{
			prev=cur;
			cur=cur->_next;
		}
		prev->_next=NULL;
		free(cur);
		cur=NULL;
	}
}
void test()
{
	Listnode* head=NULL;
	Init(head);
    push(head,1);
	push(head,2);
	push(head,3);
	/*pop(head);*/
	print(head);
	Listnode* tmp=Find(head,1);
	DeleteNode(head,head);
	print(head);

}
int main()
{
	test();
	system("pause");
	return 0;
}

结果:

时间: 2024-10-17 10:31:48

在O(1)时间删除链表节点的相关文章

LeetCode之“链表”:在O(1)时间删除链表节点

下边讨论暂不包括尾节点. 一般来说,我们要删除链表中的一个节点是需要知道其上一节点的.但我们真的需要吗? 其实我们可以将待删节点的下一节点的值和指向的下一节点赋予待删节点,然后删除待删节点的下一节点.具体示例程序如下: 1 //O(1)时间删除链表节点,从无头单链表中删除节点 2 void deleteRandomNode(Node *cur) 3 { 4 assert(cur != NULL); 5 assert(cur->next != NULL); //不能是尾节点 6 Node* pNe

剑指Offer之在O(1)时间删除链表节点

题目描述 给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 解题思路 在单向链表中删除一个节点,最常规的做法无疑是从链表的头结点开始,顺序的遍历查找要删除的节点,并在链表中删除该节点.这种思路由于需要顺序查找,时间复杂度自然就是$O(n)$了. 之所以需要从头开始查找,是因为我们需要得到将删除的节点的前面一个节点.在单向链表中,节点中没有指向前一个节点的指针,所以只好从链表的头结点开始顺序查找.那是不是一定需要得到被删除的节点的前一个节点呢?答案是否定的.我们可以很方便

剑指offer—第三章高质量代码(o(1)时间删除链表节点)

题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点,链表节点与函数的定义如下:struct ListNode{int m_nValue;ListNode* m_pValue;};void DeleteNode(ListNode** pListNode,ListNode * pToBeDeleted){} 思路:将要删除的节点的下一个节点的值赋值给i,删除下一个节点,但要考虑到删除的节点是最后一个节点并且该链表不止有一个节点的情况和该链表只有一个节点,该节点既是头节点也

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

问题描述:给定单相链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 这个比较简单,做不做解释,直接看参考代码,不过有一点就是要注意,还是要看删除的节点类型,不能保证总是O(1)时间 参考代码: void DeleteNode(ListNode** pHead,ListNode *pTobeDelete){    if ((pHead == NULL) || (*pHead == NULL) || (pTobeDelete == NULL))    {        return

剑指offer---以O(1)时间删除链表节点

问题:删除链表节点 要求:以O(1)时间 对于删除指定索引的链表元素大家都很熟悉,思路一般是从头遍历链表直到指定索引位置删除元素,然后维护一下指针即可,时间复杂度O(n).代码如下: 1 // 删除position位置的数据,并返回 2 int List::erasePosition(int position){ 3 if(position<0 || position>(List::size()-1)){ 4 cout<<"position error, please c

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

按照以往的习惯,这种题我们需要遍历整个链表,找到需要删除节点的前一个节点,这样我们就可以操作删除的方法了,这种方法需要O(n)的时间复杂度,但这里要求我们在O(1)的时间下完成.我们只能想其他的方法. 算法思想:其实我们也不需要知道删除节点前一个节点.我们的做法是将删除节点的后边一个节点的值赋给要删除的节点(即把要删除节点的值覆盖),然后将删除节点后边的节点删除(delete)即可.其中我们还需要检查要删除节点的位置,具体问题具体分析,要做到全面. 算法实现: 1 typedef struct

经典算法学习——在O(1)时间删除链表节点

这道算法题同样是剑指Offer中的一道题,题目描述为:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点.其实我们知道,想要在单向链表中找到某个节点并删除它,复杂度为O(n),因为必须从头遍历才能找到它(最重要的是因为要找到它的前一个节点.)所以想要O(1)完成,必须想其他的方法. 目前重要的一个信息就是已经有一个节点指针指向当前要删除的节点.这就比较好办了.我们可以非常方便的找到它的后继节点,然后把后继节点的值赋值给当前要删除的节点,然后再去删除那个后继节点.这样,我们

【链表】在O(1)的时间删除链表的节点

1 /** 2 * 在O(1)的时间删除链表的节点 3 * 4 * @author 5 * 6 */ 7 public class Solution { 8 9 public static void deleteNode(Node head, Node deletedNode) { 10 if (null == head || null == deletedNode) { 11 return; 12 } 13 14 if (deletedNode.next != null) { // 删除的不是

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

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