Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 堆栈的链表实现_Algorithm_Linked List_Stack_Doubly Linked List - Fatal编程技术网

Algorithm 堆栈的链表实现

Algorithm 堆栈的链表实现,algorithm,linked-list,stack,doubly-linked-list,Algorithm,Linked List,Stack,Doubly Linked List,下面是我使用linkedlist实现的堆栈 STACK using linked list STACK-EMPTY: if L.head == NIL return True else return False PUSH(x): x.next = L.head if L.head != NIL L.head.prev = x L.head = x x.prev = NIL POP(): x = L.head L.head = x.next x.next.prev = L

下面是我使用linkedlist实现的堆栈

STACK using linked list 

STACK-EMPTY:
if L.head == NIL
    return True
else return False

PUSH(x):
x.next = L.head 
if L.head != NIL
    L.head.prev = x
L.head = x
x.prev = NIL

POP():
x = L.head
L.head = x.next
x.next.prev = L.head
return x
你能验证一下吗?如何改进


谢谢

您可以改进数据结构的一致性:

  • 列表头的
    prev
    始终为
    NIL
  • 不在列表中的元素将
    next
    prev
    设置为NIL
  • 采取1。考虑到您的POP存在不一致性,这可能是错误的来源:当您弹出一个元素时,头部的
    prev
    就是头部本身,当您按下一个元素时,头部的
    prev
    是零。

    试试这个

    定义:

    • S.top
      是指向堆栈顶部
      X
      类型的某个节点的指针
    • X
      是一个具有两个指针的节点,
      top
      base
    • X.top
      指向堆栈顶部的下一个节点
    • X.base
      指向堆栈底部的下一个节点(底部)
    首先初始化堆栈顶部指针:

    STACK-INITIAL:
    S.top = NIL
    return true  // Never fails
    
    空堆栈测试:

    STACK-EMPTY:
    return (S.top == NIL)
    
    在堆栈上推送节点
    x

    PUSH(x):
    x.top = NIL     // Top of stack, therfore top is NIL
    x.base = S.top  // base is previous top
    S.top = x       // x is now top of stack  
    return true
    
    弹出并返回堆栈顶部(这是唯一“有趣”的部分):

    想一想。。。我在上面使用了一个双链接列表,因为 看起来你用的就是这个。但是,您只需要一个 链接指向堆栈底部的单链表。 请注意,上述算法中的
    x.top
    指针非常简单 无用(设置但从未引用)。只要跟踪堆栈顶部(S.top)就可以了 您需要做的是在POP操作期间跟踪堆栈

    对评论的回应

    当一个元素从堆栈中弹出时,其所有关联的 指针应设置为NIL。这是因为它不再是一部分 因此不应指向任何堆栈元素。我加了那一点 我的原始答案(见上文)

    以类似的方式,新的栈顶元素(除非堆栈变为空) 需要将其指针指向其上方的元素 设置为NIL(因为它上面的元素已被删除)。 在我的示例中,这就是
    S.top.top=NIL
    stuff是关于(
    S.top
    指向顶层堆栈元素,因此
    S.top.top
    是 该元素的顶部指针)。我想你也会用
    x.next.prev=NIL
    ,, 假设
    x
    是您使用的元素,而不是NIL本身。在伪代码中,它看起来 类似于
    x.next.prev=L.head
    将使堆栈顶部元素的prev指针指向自身 因为
    L.head
    被设置为
    x.next
    (就在这之前的新栈顶)

    最后,我质疑为什么要使用双链接列表 实现一个堆栈,只有一个带有指向
    它下面的下一个元素是必需的

    您使用双链接列表的特殊原因是什么?您可以使用单个链接列表实现堆栈,因为不需要prev指针。这似乎是codereview的一个问题。SEthanks没有意识到在我的伪代码中,
    L.head
    指向堆栈中的第一个元素,因此
    x.next=L.head
    可以归结为
    x.base=s.top
    L.head=x
    相当于你的
    S.top=x
    ,然后
    x.top=NIL
    就是我的
    x.prev=NIL
    ,我可以把它放在最后,对吧?但我想我还需要让堆栈中前一个元素的prev(top)指针指向x,如果L.head!=NIL L.head.prev=x。那么:您能确认我的代码是正确的吗?还有,PUSH()方法中的最后一条语句不是必须的吗??谢谢一种同样味道的乳液,是不是POP()必须使用
    x.next.prev=L.head
    ?thanks@macscholes参见回复中对评论的回复
    POP():
    x = S.top          // Top node on stack (could be NIL)
    if S.top != NIL    // Check in case stack was empty
      S.top = x.base   // New top = next node toward base
      x.base = NIL     // Disconnect x from stack
      if S.top != NIL  // Is stack now empty?
        S.top.top = NIL // No, set top node's top pointer to NIL
    return x            // x could be NIL if stack was empty