【问题标题】:how do i make a stack out of a linked list? [duplicate]如何从链表中创建堆栈? [复制]
【发布时间】:2013-01-21 02:03:35
【问题描述】:

我正在尝试创建一个堆栈来获取一个字符串并将每个字符串字符添加到其中,但有人告诉我使用 LinkedList 会更有效。我将如何使用 LinkedList 来创建和操作堆栈?

一个例子将不胜感激!

【问题讨论】:

  • 效率更高?为什么?
  • @Thilo 因为当我执行“Stack”时,我不断收到错误。
  • Re: 不断出错?代码甚至不起作用,你怎么知道它没有效率?
  • @Jay 您不能在泛型中使用原始类型(char、int 等)。试试Stack<Character>
  • 查看我的答案 - 立即解决问题 :) 始终始终发布您的代码。

标签: java


【解决方案1】:

好的,问题是您根本没有使用First。请尝试以下操作:

public class Example
{
    private LinkedList aList = new LinkedList();

    public void push(char c) {
        aList.addFirst(c);
    }
    public Object pop() {
        return aList.removeFirst();
    }
    public boolean empty() {
        return aList.isEmpty();
    }
    public static void main(String[] args)  {
        Stack exmpStack = new Stack();
        String ranString = "Dad";
        for (int i = 0; i < ranString.length(); i++)  {
            exmpStack.push(ranString.charAt(i));
        }
        while (!exmpStack.empty())  {
            System.out.print(exmpStack.pop());
        }
    }
}

因为您从不使用First,所以它始终是null - 所以您的循环根本不会运行!完全不用它,只需使用 isEmpty() 函数中的构建。

编辑:当然,您根本不需要这些功能 - 以下内容可以正常工作:

public class Example
{
    private LinkedList aList = new LinkedList();

    public static void main(String[] args)  {
        String ranString = "Dad";
        for (int i = 0; i < ranString.length(); i++)  {
            aList.push(ranString.charAt(i));
        }
        while (!aList.isEmpty())  {
            System.out.print(aList.pop());
        }
    }
}

现在这仍然有点不安全 - 您可以使用以下内容更进一步:

private LinkedList<Character> aList = new LinkedList<>();

这样会更安全一些,并且返回 Characters 而不是 Objects - 并且 Characters 可以隐式转换为 char :)

【讨论】:

  • 太棒了!非常感谢!!
  • 您可能希望从第二个示例中删除 exmpStack。
  • @DavidConrad 对,谢谢
【解决方案2】:

Java 的 LinkedList 是一个双向链表,具有高效的访问器来获取、添加和删除列表末尾和顶部的元素,因此您可以使用这些方法来模拟堆栈。

【讨论】:

  • 您能举个例子吗?我不确定代码会是什么样子
【解决方案3】:

LinkedList 提供比堆栈更多的操作。

您使用堆栈来推送和弹出字符串中的字符。但是,您只能按照与插入字符串的方式相反的顺序检索字符。那么你确定你是否想要这种行为。

链表允许您从头/尾添加/检索数据。

【讨论】:

  • 是的,我知道这一点,我可以接受。
  • 我认为,如果需要堆栈,则应提供堆栈以维护封装原则。在堆栈中提供列表方法会引发错误,因为如果绕过其通常的合同,堆栈可能会受到损害。
  • @MihaiDanila 你是对的。我误解了这个问题
【解决方案4】:

LinkedList 确实更高效,因为Stack 依赖于Vector 带来了同步方法。在单线程应用程序中,使用后者意味着付出同步代价而没有任何好处。即使在多线程应用程序中,您也可能需要对同步进行更多控制。

这是一个可能的基于 LinkedList 的解决方案。请注意使用组合而不是继承。这将为您提供一个行为良好的 Stack,该 Stack 不会被使用 List 相关的方法滥用。

class MyStack<T> {
    private List<T> list = new LinkedList<T>();

    public void push(T object) { list.add(0, object); }

    public T pop(T object) {
        if (isEmpty()) throw new NoSuchElementException();
        return list.remove(0);
    }

    public boolean isEmpty() { return list.isEmpty(); }
}

尽管如此,如果您的堆栈仅适用于您的问题所暗示的字符串字符,您可能希望直接在动态字符数组上模拟堆栈。我将把它作为练习留给读者,或者我可能会在以后的编辑中提供它。

【讨论】:

  • 看起来我为看起来像家庭作业的事情提供了一个高级答案。感谢 -1,伙计!
  • 那不是我给你的-1,感谢你的帮助。
【解决方案5】:

这里是示例:Stack implementation。希望对您有所帮助。

它是用 C# 完成的,但你明白了

【讨论】:

  • 这让我有点困惑....但我很感激您的意见!
  • 什么令人困惑?这个想法是你总是添加 T 作为第一个并总是从链表中删除第一个节点
猜你喜欢
  • 2016-09-28
  • 2015-05-24
  • 2018-03-21
  • 2021-12-10
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 2017-03-15
  • 1970-01-01
相关资源
最近更新 更多