图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

栏目: 数据库 · 发布时间: 7年前

内容简介:在开始这个问题之前,先想想,如果给定单链表中的某个结点,如何在单链表中删除该节点?对于一个单链表,它每个结点的数据结构除了存储自身的数据之外,还需要记录链表上,下一个结点的地址,通常我们将这个地址称之为后续指针 next。

图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

在开始这个问题之前,先想想,如果给定单链表中的某个结点,如何在单链表中删除该节点?

对于一个单链表,它每个结点的数据结构除了存储自身的数据之外,还需要记录链表上,下一个结点的地址,通常我们将这个地址称之为后续指针 next。

图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

那如上图所示,我想删除其中的 C 结点,需要做什么操作?很简单,将 B 结点的后续指针 next 指向 D 结点即可。

图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

此处应该清晰了,要删除链表上的某个结点,我们需要知道三个结点:

  • 待删除的结点。
  • 待删除结点的前驱结点。
  • 待删除结点的后续结点。

思路:实际删除下一个结点

再来回顾最开始的问题,当我们已知某个结点的时候,它的后续结点我们也是知道的。唯一的问题,就是他的前驱结点我们不知道。

最简单的解决方法,就是将链表遍历一遍,获得待删除结点的前驱结点,对其进行操作。

当涉及到遍历链表的时候,时间复杂度妥妥的变成 O(n),这就与题不符了。

而问题主要卡在了,我们如何知道待删除结点的前驱结点。试着换一个思路想想,我们只需要删除该结点存储的数据,而并不是删除该结点对应地址中的内容。

那么就可以将待删除结点的数据,和它的后续结点的数据进行互换,然后对它的后续结点进行删除操作,以此来达到 O(1) 时间复杂度的单链表删除。

图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

问题:待删除节点是最后一个节点

这个思路还存在一个问题,我们实际删除的是待删除节点的下一个节点。还记得前面说,删除单链表中的某个结点,实际上是需要知道三个结点的。

那么,如果删除的结点,是单链表的最后一个结点,怎么办?

这时我们仍然需要从链表的头结点开始遍历,得到待删除节点的前驱节点,并完成删除操作,时间复杂度恢复到 O(n)。

而题目要求我们需要在 O(1) 的时间复杂度内完成删除操作,这样是不是不符合题目要求呢?

其实不然,假设单链表总共有 n 个节点,这种算法在 n-1 的情况下时间复杂度都是 O(1),只有在待删除结点为单链表的最后一个结点时,时间复杂度才会恢复到 O(n),那么平均时间复杂度 [(n-1)*O(1)+O(n)]/n,计算下来仍然为 O(1)。

图解:单链表删除,不遍历链表也能做(时间复杂度O(1))

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

戳这里,看该作者更多好文


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art of Computer Programming, Volume 2

The Art of Computer Programming, Volume 2

Knuth, Donald E. / Addison-Wesley Professional / 1997-11-04 / USD 79.99

Finally, after a wait of more than thirty-five years, the first part of Volume 4 is at last ready for publication. Check out the boxed set that brings together Volumes 1 - 4A in one elegant case, and ......一起来看看 《The Art of Computer Programming, Volume 2》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换