堆栈的Java实现

时间:2019-06-30 19:31:19

标签: java data-structures stack time-complexity

Java中是否有一个类可以从数据结构书中实现Stack的概念,即LIFO,pop为O(1)并推入O(1)?

我读了一点java.util.Stack的代码,push似乎不是O(1)-push可以调用Vector.grow(),并且可以占用O(n)(我知道摊销O(1),但我一直希望始终按O(1)

我想了解为什么java.util.Stack是按原样设计的,而不是按照堆栈的理论原理

5 个答案:

答案 0 :(得分:6)

ArrayDequeLinkedList更好。

因为它由数组支持,而不是将各个元素存储在单独的节点实例中,所以性能要高得多。

根据tweetsLinkedList的作者Josh Bloch的说法:

  

有人真的使用LinkedList吗?我写了它,但是我从不使用它。

and

  

ArrayDeque使堆栈,队列或双端队列保持良好状态

答案 1 :(得分:1)

您可以使用实现LinkedList接口的ArrayDequeDeque,并且此接口具有类似堆栈的方法poppush。因为LinkedListArrayDeque实现了此接口,所以我们可以像使用Stack一样使用它们。

来自Deque的文档:

  

双端队列也可以用作LIFO(后进先出)堆栈。此接口应优先于旧版Stack类使用。当双端队列用作堆栈时,元素从双端队列的开头被压入并弹出。

因此,如您所见,Deque的实现应优先于旧版Stack类。

答案 2 :(得分:0)

tl; dr

Stack现在是旧代码

java.util.Stack类现在是legacy,是从另一个旧类java.util.Vector扩展而来的。您不应该使用这些类。您也不应该将它们作为闪亮的例子进行研究。

Java Collections框架

这两个类别都被Java Collections Framework取代了在二十年前。

对于LIFO的行为,您应该查看实现queue interfacesdeque interfaces的类。

java.util.Queue接口在与Java捆绑在一起的许多类中实现。

  • AbstractQueue
  • ArrayBlockingQueue
  • ArrayDeque
  • ConcurrentLinkedDeque
  • ConcurrentLinkedQueue
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue
  • LinkedList
  • LinkedTransferQueue
  • PriorityBlockingQueue
  • PriorityQueue
  • SynchronousQueue

您可能会在第三方库(可能是Google Guava)的其他地方找到实现的LIFO集合。

LinkedList

正如其他人所述,首先要考虑的是LinkedList的O(1)行为,如How is LinkedList's add(int, E) of O(1) complexity?所述。

答案 3 :(得分:0)

堆栈或队列都可以通过Linkedlist实现。

pop():从堆栈中删除顶部的项目。

push():在堆栈顶部添加一个项目。

public class MyStack<T> {

   private StackNode<T> top;
    private static class StackNode<T> {

        private T data;
        private StackNode<T> next;

        public StackNode(T data) {
            this.data = data;
        }
    }

    public T pop() {
        if (top == null) throw new EmptystackException();
        T item = top.data;
        top = top.next;
        return item;
    }

    public void push(T item) {

        StackNode<T> t = new StackNode<T>(item);
        t.next = top;
        top = t;
    }
}

答案 4 :(得分:0)

堆栈是线性数据结构。它在LIFO(后进先出机制)下工作,并且具有3个基本操作:Pop(),Push()和peek()。推和弹出操作只能在称为top的一端执行。 peek()操作用于显示堆栈中的元素。

下面是STACK的JAVA实现。我们将存储在Stack中的数据类型为String

当堆栈已满时,它称为“ OVERFLOW”,而当堆栈为空时,我们将其称为“ UNDERFLOW”

public class StackOfString {

int top = -1;
String[] myStack;

public StackOfString() {
    this.myStack = new String[5];
}

public void pop() {
    if (top != -1) {
        System.out.println("Item to be Poped: " + myStack[top]);
        myStack[top] = null;
        top -= 1;
    } else {
        System.out.println("Stack is UNDERFLOW!!!");
    }
}

public void push(String str) {
    if (isFull()) {
        top += 1;
        myStack[top] = str;
    }else {
        System.out.println("Stack is OVERFLOW!!!");
    }
    

}

public boolean isFull() {
    if (top < (myStack.length -1)) {
        return true;
    } else {
        return false;
    }
}

public void peek() {
    for (String string : myStack) {
        if (string != null)
            System.out.println(string);
    }
}}

public class Client {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    StackOfString stackOfString = new StackOfString();

    stackOfString.pop();

    stackOfString.push("A");
    stackOfString.push("B");
    stackOfString.push("C");
    stackOfString.push("D");
    stackOfString.push("E");
    stackOfString.peek();
    stackOfString.push("F");

    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
    stackOfString.pop();
}}

这是输出:

Click here to see Output