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

简介: 题目:给定一个单向链表(只有指向下一个结点的指针)的头结点和某一个结点的指针,求怎样在O(1)的时间删除这个给定结点。分析:1.  最朴素的算法是从头结点开始搜索到给定结点前一个结点,然后把结点删除。


题目:给定一个单向链表(只有指向下一个结点的指针)的头结点和某一个结点的指针,求怎样在O(1)的时间删除这个给定结点。


分析:

1.  最朴素的算法是从头结点开始搜索到给定结点前一个结点,然后把结点删除。这种方法的时间复杂度为0(n),所以不能在O(1)的时间内删除该结点


2. 要求在O(1)的时间内删除某个结点,肯定是利用单向链表的性质。给定单向链表只有指向下一个结点的指针,我们无法得到前面一个结点的指针。所以我们可以考虑换个思路。

    (1)假设要删除的链表如下


    (2)因为给定结点2的指针,那么通过下一个结点指针可以得到结点3的指针。所以实际上删除结点2等价于把结点3复制一份到结点2中,然后删除结点3,如下图


   (3)所以实际上,就是把给定结点的下一个结点复制给当前结点然后删除下一个结点。这样就可以在O(1)的时间内删除某一个结点


注意:

1. 由于涉及到下一个结点,所以要考虑多种情况

  (1)删除结点是头结点

  (2)删除结点在中间,既不是头结点也不是尾结点

  (3)删除结点是尾结点

2. 对于这些情况要分类讨论 

   总的分成两类,删除结点的下一个结点是否为空和不空

   (1)如果删除结点的下一个结点为空,说明删除结点是尾结点。则这个时候要采用从头遍历,因为没有办法把空结点复制给当前结点,这个是必须O(n)枚举。注意链表有且仅有一个结点并删除尾结点情况

   (2)如果删除结点的下一个结点不为空,则直接把下一个结点复制给当前结点,然后删除下一个结点即可


代码:

//链表结点
struct ListNode{
    int value;
	ListNode *nextNode;	   
};

//删除一个结点,涉及到修改指针传递指针的指针 
void DeleteNode(ListNode **headNode, ListNode **deleteNode){
    //不合法数据
	if((*headNode) == NULL || (*deleteNode) == NULL){
	    return;
    } 
    //删除结点
	ListNode *deleteNodeNextNode = (*deleteNode)->nextNode;
	//如果下一个结点是为空,直接删除该点 
	if(deleteNodeNextNode == NULL){
        //遍历删除
		ListNode *tmpNode = (*headNode);
		while((tmpNode != NULL) && (tmpNode->nextNode != (*deleteNode))){
		      tmpNode = tmpNode->nextNode;
	    } 
	    //如果当前链表有且只有一个点则tmpNode变成NULL 
	    if(tmpNode != NULL){
		    tmpNode->nextNode = NULL;
		}
		delete (*deleteNode);
		(*deleteNode) = NULL; 
    } 
    else{
        //把下一个结点值复制给当前结点 
		(*deleteNode)->value = deleteNodeNextNode->value;
        (*deleteNode)->nextNode = deleteNodeNextNode->nextNode;
         //删除下一个结点 
		 delete deleteNodeNextNode;
		 deleteNodeNextNode = NULL;
    }
} 



目录
相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
69 1
|
26天前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
14 1
|
2月前
链表的中间结点
链表的中间结点
179 57
|
5月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
49 0
|
1月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
3月前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点
|
4月前
【数据结构OJ题】链表中倒数第k个结点
牛客题目——链表中倒数第k个结点
38 1
【数据结构OJ题】链表中倒数第k个结点
|
3月前
【刷题记录】链表的中间结点
【刷题记录】链表的中间结点
|
4月前
【数据结构OJ题】链表的中间结点
力扣题目——链表的中间结点
27 0
【数据结构OJ题】链表的中间结点
|
5月前
|
算法
19.删除链表的倒数第N个结点
19.删除链表的倒数第N个结点