Java语言怎么用双向列表定义双向堆栈

Java语言怎么用双向列表定义双向堆栈?双向堆栈的pop1和pop2分别怎么实现的呢

效果如图:

img


思路:
Java中,可以使用双向列表(双向链表)来定义双向堆栈。双向列表由节点组成,每个节点包含一个数据元素以及两个指针,分别指向前一个节点和后一个节点,然后实现双向堆栈的push、pop1和pop2操作。其中,push将元素推入堆栈1或堆栈2,pop1将从堆栈1中弹出元素,而pop2将从堆栈2中弹出元素
注意 : 在pop操作中, 需要对栈顶节点进行更新,并确保节点的前后指针正确设置。
代码如下:

import java.util.NoSuchElementException;

class DoublyStack {
    private Node top1;   // 堆栈1的栈顶
    private Node top2;   // 堆栈2的栈顶
    
    // 节点类
    private class Node {
        int data;  // 数据
        Node prev; // 前一个节点
        Node next; // 后一个节点
        
        public Node(int data) {
            this.data = data;
        }
    }
    
    // 构造方法,初始化栈顶节点
    public DoublyStack() {
        top1 = null;
        top2 = null;
    }
    
    // 将元素推入堆栈1
    public void push1(int data) {
        Node newNode = new Node(data);
        if (top1 == null) {
            top1 = newNode;
        } else {
            newNode.next = top1;
            top1.prev = newNode;
            top1 = newNode;
        }
    }

    // 将元素推入堆栈2
    public void push2(int data) {
        Node newNode = new Node(data);
        if (top2 == null) {
            top2 = newNode;
        } else {
            newNode.next = top2;
            top2.prev = newNode;
            top2 = newNode;
        }
    }

    // 从堆栈1中弹出元素
    public int pop1() {
        if (top1 == null) {
            throw new NoSuchElementException("堆栈1为空");
        }

        int data = top1.data;
        top1 = top1.next;

        if (top1 != null) {
            top1.prev = null;
        }
        
        return data;
    }

    // 从堆栈2中弹出元素
    public int pop2() {
        if (top2 == null) {
            throw new NoSuchElementException("堆栈2为空");
        }

        int data = top2.data;
        top2 = top2.next;

        if (top2 != null) {
            top2.prev = null;
        }
        
        return data;
    }
}

public class Main {
    public static void main(String[] args) {
        DoublyStack stack = new DoublyStack();
        
        // 向堆栈1推入元素
        stack.push1(10);
        stack.push1(20);
        stack.push1(30);
        
        // 从堆栈1弹出元素
        int poppedElement1 = stack.pop1();
        System.out.println("从堆栈1弹出的元素为: " + poppedElement1);
        
        // 向堆栈2推入元素
        stack.push2(40);
        stack.push2(50);
        
        // 从堆栈2弹出元素
        int poppedElement2 = stack.pop2();
        System.out.println("从堆栈2弹出的元素为: " + poppedElement2);
    }
}


感觉回答还可以,请采纳,谢谢

在Java中,你可以使用双向列表(LinkedList)来定义双向堆栈。LinkedList类实现了Deque接口,该接口提供了堆栈和队列的功能。下面是使用双向列表定义双向堆栈的示例代码:

import java.util.Deque;
import java.util.LinkedList;

public class DualStack {
    private Deque<Integer> stack1;  // 用于存储pop1操作的元素
    private Deque<Integer> stack2;  // 用于存储pop2操作的元素
    
    public DualStack() {
        stack1 = new LinkedList<>();
        stack2 = new LinkedList<>();
    }
    
    public void push1(int value) {
        stack1.push(value);
    }
    
    public void push2(int value) {
        stack2.push(value);
    }
    
    public int pop1() {
        if (stack1.isEmpty()) {
            // 如果pop1的栈为空,将stack2中的元素依次转移到stack1中
            while (!stack2.isEmpty()) {
                stack1.push(stack2.pop());
            }
        }
        return stack1.pop();
    }
    
    public int pop2() {
        if (stack2.isEmpty()) {
            // 如果pop2的栈为空,将stack1中的元素依次转移到stack2中
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
        }
        return stack2.pop();
    }
}

上述示例中,使用两个LinkedList实例stack1和stack2来分别存储pop1和pop2操作的元素。push1和push2方法分别用于将元素推入stack1和stack2。当执行pop1操作时,如果stack1为空,将从stack2中依次弹出元素并推入stack1中,然后返回stack1的顶部元素。同样,当执行pop2操作时,如果stack2为空,将从stack1中依次弹出元素并推入stack2中,然后返回stack2的顶部元素。

这样,就可以使用双向列表实现双向堆栈,并且能够分别进行pop1和pop2操作。

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这篇博客: Java中栈的解析中的 Pop方法: 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    public synchronized E pop() {
        E     obj;
        int     len = size();
        obj = peek();
        removeElementAt(len - 1);
        return obj;
    }
    public synchronized void removeElementAt(int index) {
        modCount++;
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +  elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        elementCount--;
        elementData[elementCount] = null; /* to let gc do its work */
    }
    

    pop方法就是将栈顶的元素弹出来。如果栈里有元素,就取最顶端的那个,否则就要抛出异常。源码中,通过peek()方法取到顶端的元素,然后我们需要用removeElementAt()方法将最顶端的元素移除。 

     removeElementAt方法的原理是首先判断边界,是否出了边界,如果出了边界,就抛出异常,否则,将待删除元素的后面元素依次覆盖前面一个元素,直到待删除的元素被覆盖,然后长度减1,将最后一个元素的值设置为null,接着gc会回收它。

  • 以下回答来自chatgpt:

    要使用Java语言的双向列表实现双向堆栈,可以按照以下步骤进行操作:

    1. 首先,创建一个Node类来表示双向列表中的节点。节点应该包含一个数据字段以及两个指针字段,分别指向上一个节点和下一个节点。示例代码如下所示:
    public class Node<T> {
        private T data;
        private Node<T> prev;
        private Node<T> next;
    
        public Node(T data) {
            this.data = data;
            this.prev = null;
            this.next = null;
        }
    
        // getters and setters
    }
    
    1. 接下来,创建一个双向列表类来管理节点。列表应该包含一个头部指针,指向列表的第一个节点,并且应该有一个尾部指针,指向列表的最后一个节点。示例代码如下所示:
    public class DoublyLinkedList<T> {
        private Node<T> head;
        private Node<T> tail;
    
        public DoublyLinkedList() {
            this.head = null;
            this.tail = null;
        }
    
        // 添加一个节点到列表的头部
        public void push(T data) {
            Node<T> newNode = new Node<>(data);
            if (head == null) {
                head = newNode;
                tail = newNode;
            } else {
                newNode.next = head;
                head.prev = newNode;
                head = newNode;
            }
        }
    
        // 从列表的头部删除一个节点并返回其值
        public T pop1() {
            if (head == null) {
                throw new NoSuchElementException("The stack is empty.");
            }
            Node<T> poppedNode = head;
            head = head.next;
            if (head != null) {
                head.prev = null;
            } else {
                tail = null;
            }
            return poppedNode.data;
        }
    
        // 添加一个节点到列表的尾部
        public void offer(T data) {
            Node<T> newNode = new Node<>(data);
            if (tail == null) {
                head = newNode;
                tail = newNode;
            } else {
                newNode.prev = tail;
                tail.next = newNode;
                tail = newNode;
            }
        }
    
        // 从列表的尾部删除一个节点并返回其值
        public T pop2() {
            if (tail == null) {
                throw new NoSuchElementException("The stack is empty.");
            }
            Node<T> poppedNode = tail;
            tail = tail.prev;
            if (tail != null) {
                tail.next = null;
            } else {
                head = null;
            }
            return poppedNode.data;
        }
    
        // getters and setters
    }
    

    以上就是使用Java语言的双向列表实现双向堆栈的具体解决方案。您可以根据需要对代码进行自定义和扩展。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^