在O(1)中为LinkedStack编写pop()方法

时间:2018-02-06 01:02:47

标签: c++ linked-list stack big-o

如何在O(1)中为LinkedStack编写pop()方法? 我的LinkedStack课程中有两位私人数据成员:ListNode* headListNode* tail

head指向LinkedStack的开头,tail指向LinkedStack的结尾。

pop()将移除ListNode指向的tail,然后tail将指向之前<{>}的ListNode > tail

了解这一点,我将如何在pop()中撰写O(1)?显然,我可以编写一个for循环,在ListNode之前抓住之前的tail,但pop()不会O(1)

由于这是作业,我不是在寻找代码解决方案,只是提示正确的方向。

编辑:我可能看到的一个解决方案是拥有ListNode* prev数据成员,该成员始终指向tail之前的前一个ListNode。但我觉得这是一种更有效的方式......

Edit2 :谢谢@ user4581301。 假设pop()为空时不会调用LinkedStack

1 个答案:

答案 0 :(得分:3)

正如您所述,任何情况,您必须遍历列表以找到特定元素,这将使得无法满足常量时间要求。这包括一个单链表,您可以将项目推送到最后。 双向链接列表将更容易,因为您可以从尾部到倒数第二项而不进行遍历。

但是,我不确定为什么你要推到最后。如果您要在列表的前面上推送新元素,那么pushpop实现固定时间是微不足道的。

就此而言,我的意思是(伪代码,正如你所提到的,&#34;这是作业和#34;):

def push(x):
    allocate node          # get new node and set data.
    node.data = x

    node.next = head       # insert at head of list
    head = node

def pop():
    assert head != null    # catch pop on empty stack

    node = head            # get first node and data
    retval = node.data

    head = head.next       # set head to be second node

    free node              # free node and return data
    return retval

您可以看到任何操作都没有遍历列表。首先,将7推送到一堆素数:

Starting list:
    head
        \
         5 -> 3 -> 2 -|

Create new node, point to current head:
     head
         \
     7 -> 5 -> 3 -> 2 -|

Point head at new node:
    head
        \
         7 -> 5 -> 3 -> 2 -|

现在让我们弹出同样的价值。

Starting list:
    head
        \
         7 -> 5 -> 3 -> 2 -|

Save head as node, and value to return (7):
    head
        \
         7 -> 5 -> 3 -> 2 -|
        /
    node

Adjust head:
         head
             \
         7 -> 5 -> 3 -> 2 -|
        /
    node

Free node and return stored value (7):
    head
        \
         5 -> 3 -> 2 -|