【问题标题】:What is the time complexity for deletion in singly and doubly linked lists?在单链表和双链表中删除的时间复杂度是多少?
【发布时间】:2019-10-05 23:22:16
【问题描述】:

如果我们不知道节点的位置,那么单链表和双链表都需要O(n)时间删除吗?

我的理解是,我们需要遍历node才能知道单链表中节点的前一个指针和节点的下一个指针。因此删除单链表的时间复杂度为O(n)

对于双向链表,由于我们知道要删除的节点的previous和next指针,所以时间复杂度为O(1)

【问题讨论】:

    标签: algorithm optimization data-structures time-complexity computer-science


    【解决方案1】:

    在这两种情况下,定位节点都是O(n)(伪代码如下,在所有情况下):

    def locate(key):
        ptr = head
        while ptr != null:
            if ptr.key == key:
                return ptr
            ptr = ptr.next
        return null
    

    在双向链表中删除一个节点是O(1)只给出它的指针,因为你可以很容易地到达前一个节点:

    def del (ptr):
        if ptr == head: # head is special case
            head = ptr.next
            free ptr
            return
    
        ptr.prev.next = ptr.next
        free ptr
    

    对于同样的条件(只有指针),O(n) 删除 singly 链表中的节点,因为您需要先定位节点 before你要删除的那个:

    def del (ptr):
        if ptr == head: # head is special case
            head = ptr.next
            free ptr
            return
    
        prev = head
        while prev.next != ptr:
            prev = prev.next
        prev.next = ptr.next
        free ptr
    

    但是,两个O(n) 操作仍然 O(n),因为它线性依赖于节点的数量。

    因此,要删除一个您还没有指向的节点,在这两种情况下都是O(n),如果你这样做了,这只是为每个n 所做的工作对于单链表来说会更大天真地(作为“找到要删除的节点”然后“找到那个之前的节点”)。


    但通常情况下,您不会这样做。您的删除功能会在前进时记住前一个节点,这样,一旦您找到要删除的节点,您还会拥有它之前的节点,这样您就需要再次搜索。

    这可能是这样的,我们实际上是在您要删除的元素之前搜索元素

    def del (key):
        if head == null: # no action on empty list
            return
    
        if head.key == key: # head is special case
            temp = head
            head = head.next
            free temp
            return
    
        prev = head
        while prev.next != null:
            if prev.next.key == key:
                temp = prev.next
                prev.next = temp.next
                free temp
                return
            prev = prev.next
    

    【讨论】:

      【解决方案2】:

      除了现有的答案之外,如果我们允许移动节点的内容,还有一种方法可以从单链表常量 time 中删除一个节点,只需一个指向它的指针。我们将下一个节点的内容移动到要删除的节点中,并使下一个节点的指针指向下一个节点之后的节点。

      【讨论】:

        猜你喜欢
        • 2010-12-26
        • 2011-04-23
        • 2011-09-03
        • 2014-05-01
        • 2016-03-03
        • 2021-09-09
        • 1970-01-01
        • 2014-08-06
        • 2019-07-02
        相关资源
        最近更新 更多