【问题标题】:Implementing stack using linked lists使用链表实现堆栈
【发布时间】:2011-07-29 22:56:45
【问题描述】:

在 Java 中使用链表实现堆栈的最佳方法是什么?

编辑:我将最好定义为使用干净代码最有效。我已经使用数组来实现堆栈,但不熟悉链接列表,所以想知道是否有人可以帮助我实现类似于以下内容:

public class StackArray{

    private Object [] objArray;
    private int stackSize;

    public StackArray(){
        objArray = new Object[50];
        stackSize = 0;
    }

    public StackArray(int size){
        objArray = new Object[size];
        stackSize = 0;
    }

    //public interface methods - push, pop, top, empty & clear
    public void push(Object o)throws StackArrayException{
        if(stackSize < objArray.length){
            objArray[stackSize] = o;
            stackSize ++;
        }else{
            throw new StackArrayException("Stack Overflow");
        }
    }

    public Object pop()throws StackArrayException{
        if(stackSize != 0){
            stackSize--;
            return(objArray[stackSize]);
        }else{
            throw new StackArrayException("Stack Underflow");
        }
    }

    public void top() throws StackArrayException{
        if(stackSize != 0){
            return(objArray[stackSize-1]);
        }else{
            throw new StackArrayException("Stack Underflow");
        }
    }

    public boolean empty(){
        return (stackSize == 0):
    }

    public void clear(){
        stackSize = 0;
    }
}

编辑:如果有人感兴趣,这里是链表实现。

public class StackList{
    private Node listHead;

    protected class Node{
    protected Object datum;
    protected Node next;

    public Node(Object o, Node n){
        datum = o;
        next = n;
    }

    public StackList(){
        listHead = null;
    }

    //public interface methods - push pop top empty clear
    public void push(Object o){
        listHead = new Node(o, listHead);
    }

    public Object pop() throws StackListException{
        if(listHead!=null){
            Object top = listHead.datum;
            listHead = listHead.next;
            return top;
        }else{
            throw new StackListException("Stack Underflow");
        }
    }

    public Object top()throws StackListException{
        if(listHead != null){
            return(listHead.datum);
        }else{
            throw new StackListException("Stack Underflow");
        }
    }

    public boolean empty(){
        return (listHead == null);
    }

    public void clear(){
        listHead = null;
    }
}

【问题讨论】:

  • 定义“最佳”!你衡量什么质量?开发时间?干净的代码?运行时性能?内存使用情况? “当我把它作为家庭作业上交时我得到的成绩”?优雅?每行字符数?
  • 你想要一个堆栈(又名后进先出 / LIFO)还是一个队列(先进先出)?
  • 在pop方法中,如果返回项“NEXT”设置为null就不好了??

标签: java queue linked-list adt


【解决方案1】:

假设您真的想从头开始执行此操作,而不是使用 perfectly good existing stack implementations 之一,那么我建议:

  • 创建一个“MyStack”类来实现你想要的任何接口(也许是List?)
  • 在 MyStack 中为每个链表项创建一个“私有静态最终类 Node”内部类。每个节点都包含对 T 类型对象的引用和对“下一个”节点的引用。
  • 添加对 MyStack 的“topOfStack”节点引用。
  • push和pop操作只需要在这个topOfStack节点上操作即可。如果为空,则堆栈为空。我建议使用与标准 Java 堆栈相同的方法签名和语义,以避免以后混淆.....
  • 最后实现您需要的任何其他方法。对于奖励积分,实现“Iterable”,使其记住创建迭代器时堆栈的不可变状态,而无需任何额外的存储分配(这可能的:-) )

【讨论】:

  • 谢谢我让它工作了,但我创建了自己的节点类。
【解决方案2】:

您为什么不直接使用已有的Stack 实现?

或者更好(因为它确实是一个链表,速度快,线程安全):LinkedBlockingDeque

【讨论】:

  • 既然这不是链表实现,而是基于数组的,也许吧?
【解决方案3】:

如果你说的是一个单链表(一个节点有一个对下一个对象的引用,但不是前一个),那么这个类看起来像这样:

public class LinkedListStack {

    private LinkedListNode first = null;
    private LinkedListNode last = null;
    private int length = 0;

    public LinkedListStack() {}

    public LinkedListStack(LinkedListNode firstAndOnlyNode) {
        this.first = firstAndOnlyNode;
        this.last = firstAndOnlyNode;
        this.length++;
    }

    public int getLength() {
        return this.length;
    }

    public void addFirst(LinkedListNode aNode) {
        aNode.setNext(this.first);
        this.first = aNode;
    }

}

public class LinkedListNode {

    private Object content = null;
    private LinkedListNote next = null;

    public LinkedListNode(Object content) {
        this.content = content;
    }

    public void setNext(LinkedListNode next) {
        this.next = next;
    }

    public LinkedListNode getNext() {
        return this.next;
    }

    public void setContent(Object content) {
        this.content = content;
    }

    public Object getContent() {
        return this.content;
    }

}

当然,您需要编写其余方法才能使其正常有效地工作,但您已经掌握了基础知识。 希望这会有所帮助!

【讨论】:

    【解决方案4】:

    用于使用 LinkedList 实现堆栈 - 此 StackLinkedList 类在内部维护 LinkedList 引用。

    StackLinkedList 的 push 方法内部调用了linkedList 的insertFirst() 方法

    public void push(int value){
        linkedList.insertFirst(value);
    }
    

    StackLinkedList 的方法内部调用了linkedList 的deleteFirst() 方法

    public void pop() throws StackEmptyException {
        try{
            linkedList.deleteFirst();
        }catch(LinkedListEmptyException llee){
            throw new StackEmptyException();
        }
    }
    

    完整计划

    /**
     *Exception to indicate that LinkedList is empty.
     */
    
    class LinkedListEmptyException extends RuntimeException{
        public LinkedListEmptyException(){
            super();
        }
        
        public LinkedListEmptyException(String message){
            super(message);
        }  
    }
    
    /**
     *Exception to indicate that Stack is empty.
     */
    
    class StackEmptyException extends RuntimeException {
     
        public StackEmptyException(){
            super();
        }
    
        public StackEmptyException(String message){
            super(message);
        }
    }
    
    /**
     *Node class, which holds data and contains next which points to next Node.
     */
    class Node {
        public int data; // data in Node.
        public Node next; // points to next Node in list.
    
        /**
         * Constructor
         */
        public Node(int data){
            this.data = data;
        }
    
        /**
         * Display Node's data
         */
        public void displayNode() {
            System.out.print( data + " ");
        }
    }
    
    
    /**
     * LinkedList class
     */
    class LinkedList {
        private Node first; // ref to first link on list
    
        /**
         * LinkedList constructor
         */
        public LinkedList(){
            first = null;
        }
    
        /**
         * Insert New Node at first position
         */
        public void insertFirst(int data) {
            Node newNode = new Node(data);  //Creation of New Node.
            newNode.next = first;   //newLink ---> old first
            first = newNode;    //first ---> newNode
        }
    
        /**
         * Deletes first Node
         */
        public Node deleteFirst()
        {
            if(first==null){    //means LinkedList in empty, throw exception.               
                throw new LinkedListEmptyException("LinkedList doesn't contain any Nodes.");
            }
            Node tempNode = first; // save reference to first Node in tempNode- so that we could return saved reference.
            first = first.next; // delete first Node (make first point to second node)
            return tempNode; // return tempNode (i.e. deleted Node)
        }
    
            
        /**
         * Display LinkedList
         */
        public void displayLinkedList() {
            Node tempDisplay = first; // start at the beginning of linkedList
            while (tempDisplay != null){ // Executes until we don't find end of list.
                tempDisplay.displayNode();
                tempDisplay = tempDisplay.next; // move to next Node
            }
            System.out.println();   
        }
    }
    
    
    /**
     * For implementing stack using using LinkedList- This StackLinkedList class internally maintains LinkedList reference.
     */
    
    class StackLinkedList{
    
        LinkedList linkedList = new LinkedList(); // creation of Linked List
    
        /**
         * Push items in stack, it will put items on top of Stack.
         */
        public void push(int value){
            linkedList.insertFirst(value);
        }
    
        /**
         * Pop items in stack, it will remove items from top of Stack.
         */
        public void pop() throws StackEmptyException {
            try{
                linkedList.deleteFirst();
            }catch(LinkedListEmptyException llee){
                throw new StackEmptyException();
            }
        }
    
        /**
         * Display stack.
         */
        public void displayStack() {
            System.out.print("Displaying Stack >  Top to Bottom : ");
            linkedList.displayLinkedList();
        }
    }
    
    
    /**
     * Main class - To test LinkedList.
     */
    public class StackLinkedListApp {
        public static void main(String[] args) {
    
            StackLinkedList stackLinkedList=new StackLinkedList();
            stackLinkedList.push(39);  //push node.
            stackLinkedList.push(71);  //push node.
            stackLinkedList.push(11);  //push node.
            stackLinkedList.push(76);  //push node.
    
            stackLinkedList.displayStack(); // display LinkedList
                        
            stackLinkedList.pop();  //pop Node
            stackLinkedList.pop();  //pop Node
            
            stackLinkedList.displayStack(); //Again display LinkedList
        }
    }
    

    输出

    显示堆栈 > 从上到下:76 11 71 39

    显示堆栈 > 从上到下:71 39

    礼貌:http://www.javamadesoeasy.com/2015/02/implement-stack-using-linked-list.html

    【讨论】:

      【解决方案5】:

      使用 STL 适配器 std::stack。为什么?因为您不必编写的代码是完成任务的最快方式。 stack 经过充分测试,可能不需要您的任何关注。为什么不?因为你的代码需要一些特殊用途的需求,这里没有记录。

      默认stack使用deque双端队列,但它只需要底层容器支持“反向插入序列”,也称为.push_back

      typedef std::stack< myType, std::list<myType> > myStackOfTypes;
      

      【讨论】:

        【解决方案6】:

        这是一个使用数组和链表stack implementation的教程实现。

        视情况而定。

        数组:- 你不能调整它的大小(固定大小) LinkedList :- 它比基于数组的内存占用更多​​内存,因为它希望将下一个节点保留在内存中。

        【讨论】:

          【解决方案7】:

          我看到了许多使用 LinkedList 的堆栈实现,最后我了解了堆栈是什么......并自己实现了堆栈(对我来说它干净高效)。我希望你欢迎新的实现。代码如下。

          class Node
          {
              int     data;
              Node    top;
          
              public Node()
              {
          
              }
          
              private Node(int data, Node top)
              {
                  this.data = data;
                  this.top = top;
              }
          
              public boolean isEmpty()
              {
                  return (top == null);
              }
          
              public boolean push(int data)
              {
                  top = new Node(data, top);
                  return true;
              }
          
              public int pop()
              {
                  if (top == null)
                  {
                      System.out.print("Stack underflow<-->");
                      return -1;
                  }
                  int e = top.data;
                  top = top.top;
                  return e;
              }
          }
          

          这里是它的主要类。

          public class StackLinkedList
          {
              public static void main(String[] args)
              {
                  Node stack = new Node();
                  System.out.println(stack.isEmpty());
                  stack.push(10);
                  stack.push(20);
                  stack.push(30);
                  System.out.println(stack.pop());
                  System.out.println(stack.pop());
                  System.out.println(stack.isEmpty());
                  System.out.println(stack.pop());
                  System.out.println(stack.isEmpty());
                  System.out.println(stack.pop());
          
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-03-17
            • 1970-01-01
            • 1970-01-01
            • 2012-05-24
            • 2019-03-04
            • 2020-01-16
            相关资源
            最近更新 更多