Java - 链接堆栈实现,无法弄清楚为什么始终打印相同的数字

时间:2014-04-03 21:51:15

标签: java static stack variable-assignment computer-science

所以我一直在努力完成以下大学实验。大部分代码都提供给我们,但我们被告知要填写LinkedStack.java代码的方法。这个概念非常简单,每个Node()对象都包含一个Object类型变量(在本例中为Integer)和另一个Node()对象。 LinkedStack()类用于初始化这些节点并设置它们的数量限制。问题是,在执行StackTest.java之后,返回以下内容:

18 18 18 18 18 18 18 18 18 18
6 6 6 6 6 6

当它应该返回以下内容时:

18 16 14 12 10 8 6 4 2 0
6 5 4 3 2 1

P.S。代码被广泛评论,所以我相信你将能够找出我没有提到的任何内容。此外,StackADT只是一个简单的接口,它只是陈述LinkedStack中使用的方法。

当然,非常感谢任何帮助过的人!

以下是所有代码(对不起,我是新来的,不知道如何防止它被分组):

    // ***************************************************************
    // LinkedStack.java
    //
    // A linked implementation of an Object stack class with operations push,
    // pop, and isEmpty and isFull.
    //
    // ***************************************************************
    public class LinkedStack implements StackADT {

    private Node top; // reference to top of stack
    private int size;
    private int counter = 0;

    // ---------------------------------------------------
    // Constructor -- initializes top
    // ---------------------------------------------------
      public LinkedStack() {
        top = new Node();
        size = 10;
      }

    // ---------------------------------------------------
    // Adds element to top of stack if it's not full, else
    // does nothing.
    // ---------------------------------------------------
      public void push(Object val) {
        counter++; 
        if(counter > 0 && counter <= size) {]
          top.setNext(top);
          top.setElement(val);
        }
        else {
          top.setElement(val);
        }
      }

    // ---------------------------------------------------
    // Removes and returns value at top of stack. If stack
    // is empty returns null.
    // ---------------------------------------------------
      public Object pop() {
        if (counter > 0) {
          Object val = top.getElement();
          top = top.getNext();
          counter--;
          return(val);
        }
        else {
          return(null);
        }
      }

    // ---------------------------------------------------
    // Returns true if stack is empty, false otherwise.
    // ---------------------------------------------------
      public boolean isEmpty() {
        if(counter == 0) {
          return(true);
        }
        else {
          return(false);
        }
      }

    // ---------------------------------------------------
    // Returns true if stack is full, false otherwise.
    // ---------------------------------------------------
      public boolean isFull() {
        if(counter == size) {
          return(true);
        }
        else {
          return(false);
        }
      }
    }

Node.java:

//***********************************************************
// Node.java
// A general node for a singly linked list of objects.
//***********************************************************

public class Node {

  private Node next;
  private Object element;

//----------------------------------------------------
// Creates an empty node
//----------------------------------------------------
  public Node() {
    next = null;
    element = null;
  }

//----------------------------------------------------
// Creates a node storing a specified element
//----------------------------------------------------
  public Node(Object element) {
    next = null;
    this.element = element;
  }

//----------------------------------------------------
// Returns the node that follows this one
//----------------------------------------------------
  public Node getNext() {
    return next;
  }

//----------------------------------------------------
// Sets the node that follows this one
//----------------------------------------------------
  public void setNext(Node node) {
    next = node;
  }

//----------------------------------------------------
// Returns the element stored in this node
//----------------------------------------------------
  public Object getElement() {
    return element;
  }

//----------------------------------------------------
// Sets the element stored in this node
//----------------------------------------------------
  public void setElement(Object element) {
    this.element = element;
  }
}

StackTest.java:

// *******************************************************
// StackTest.java
//
// A simple driver that exercises push, pop, isFull and isEmpty.
// Thanks to autoboxing, we can push integers onto a stack of Objects.
//
// *******************************************************

public class StackTest {

public static void main(String[] args) {
   StackADT stack = new LinkedStack ();

   //push some stuff on the stack
   for (int i=0; i<10; i++)
     stack.push(i*2);

   //pop and print
   //should print 18 16 14 12 10 8 6 4 2 0
   while (!stack.isEmpty())
     System.out.print(stack.pop() + " ");
     System.out.println();

   //push a few more things
   for (int i=1; i<=6; i++)
     stack.push(i);

   //should print 6 5 4 3 2 1
   while (!stack.isEmpty())
     System.out.print(stack.pop() + " ");
     System.out.println();
  }
}

3 个答案:

答案 0 :(得分:3)

// ---------------------------------------------------
// Adds element to top of stack if it's not full, else
// does nothing.
// ---------------------------------------------------
  public void push(Object val) {
    counter++; 
    if(counter > 0 && counter <= size) {]
      top.setNext(top);
      top.setElement(val);
    }
    else {
      top.setElement(val);
    }

看看top.setNext(top)。这就是您获得输出的原因。

阅读评论。现在看看if .. else。当堆栈已满时,您实际上正在做某事。

编辑:看看其他方法,我可以看到整个过程中的逻辑缺陷。我建议用笔和纸来决定应该发生什么。或者,从头开始并一次实施一个方法。运行该方法并确保它按预期工作。如果可行,请添加另一个方法,测试它和以前的方法。我建议你这样做,因为我认为你对编程很新手 - 我相信这对你有好处。

答案 1 :(得分:2)

堆栈的工作原理是在堆栈顶部添加一个新节点,并设置对前一个顶级节点的下一个引用。

您在构建LinkedStack时创建一个节点,然后在push方法中将引用设置为自身的下一个节点(进行无限循环)。

在指示您按下第一个项目之前,不应创建顶级节点。最底层的项目应该将其下一个引用设置为null,以指示它下面没有更多。

public void push(Object val) {
    if(!isFull()) {
        counter++;
        Node lastTop = top;
        top = new Node(val);
        top.setNext(lastTop);
    }
}

您的isEmpty()方法只需检查top是否为空。

你的pop方法很好,但是你应该使用isEmpty方法来使代码更容易理解:

public Object pop() {
    if(!isEmpty()) {
        counter--;
        Node lastTop = top;
        top = top.getNext();
        return lastTop.getElement();
    } else {
        return null;
    }
}

答案 2 :(得分:2)

这个问题在于推送功能:

      top.setNext(top);
      top.setElement(val);

您正在设置自己的下一个元素,而不是创建一个新节点。因此,当您将元素设置为val时,您将覆盖之前的val值。

简而言之,top现在指向单节点循环中的top。相反,您应该创建一个新节点,如下所示:

Node new_top = new Node(val); 
new_top.setNext(top);
top = new_top;

这将创建一个新节点,使用推送值填充它,将其下一个指针设置为堆栈的上一个顶部,然后使用指向它的指针覆盖指向堆栈顶部的指针。

通过这些评论感谢Jason ,请注意堆栈中将有一个空节点,除非您进一步修改推送逻辑。实质上,只需在条件语句中移动计数器增量,以便在放置节点后递增计数器。

您应该重写该逻辑,甚至可能值得删除构造函数中的节点创建并在push函数中执行所有操作。