【问题标题】:Push method implementation using Stack and List ADT使用 Stack 和 List ADT 实现推送方法
【发布时间】:2015-12-01 23:11:02
【问题描述】:

我将如何使用列表 ADT 为堆栈 ADT 编写推送实现?假设我要推到堆栈的顶部,我是否必须创建一个临时列表并做一些事情来将前一个头部添加到尾部?

private someList<E> stack;

public void push(E element){
            stack.add(element);
        }



//another file
public someList<E> add(E newHead){

    return new someList<E>(newHead, this); 
}

【问题讨论】:

  • Anyone?:D 甚至指向文档也很棒。

标签: java list stack adt


【解决方案1】:

在堆栈 ADT 的实现中重要的是,您要在哪里添加 push 的新元素,以及要在哪里删除 pop 的元素。显然push(someElement); pop(); 应该保持堆栈不变。

所以我们有 2 个选择,在列表末尾或前面添加/删除元素。

public void push(E element){
        stack.add(element);
}

您已选择在列表末尾添加/删除它们。 我不知道add 方法必须做什么,但是如果它返回一个代表新堆栈的新someList,那么私有stack 字段应该分配这个新创建的堆栈!

注意,如果add的目的是改变当前头部(用这个替换当前的TOS(=栈顶)),那么你可以简单地写成如下

public someList<E> add(E newHead){
    pop(); // remove TOS
    push(newHead); // Add newHead as the new TOS
    return this.stack; 
}

我已经为String 实现了stack ADT。我把它作为一个简单的练习来改变它以满足您的需求(使用 someList 而不是 List 并使用泛型)。

public class Stack {
    private List<String> stack = new ArrayList<String>();

    public void push(String element){
        stack.add(element);
    }

    public List<String> add(String newHead){
        stack = new ArrayList<String>(stack); // you should do "stack = new someList<E>(newHead, this);"
        return stack; // return the new stack
    }

    public String pop() {
        String res = stack.get(stack.size() - 1);
        stack.remove(stack.size() - 1); // 
        return res;
    }

    public void printStack() {
        System.out.println("TOS (Top Of Stack)");
        for(int i = stack.size() - 1; i >= 0; i--)
            System.out.println(stack.get(i));
        System.out.println("EOS (End Of Stack)");
    }
}

// Test it
...
String a = "a", b = "b";
Stack stck = new Stack();

stck.push(a);
stck.push(b);
stck.push(b);
stck.push(a);
stck.pop();

stck.printStack();
...

这是测试用例期间堆栈的变化方式。

TOS (Top Of Stack)         

a  --->   b   --->   b   --->   a   --->   b
          a          b          b          b
                     a          b          a
                                a

EOS (End Of Stack) 

请注意,在stack ADT 的这个实现中,我们通过从列表尾部添加/删除元素(更准确地说是arrayList)从堆栈中推送/弹出元素。这非常适合与 java 的 arrayList 一起使用,因为在 O(1) 中添加一个元素到列表的尾部或删除最后一个元素。

指定插入位置的方法必须将所有数组元素从插入处复制到右侧

(Source)

在使用自己的 someList 实现时,您必须检查是否同样适用。但是,如果将一个元素添加到列表的尾部(或删除最后一个元素)需要您遍历整个列表(例如,单个链表就是这种情况,因此 O(n)),那么添加/删除第一个元素应该在 O(1) 中。

在这种情况下,您应该更改stack ADT 的实现,以便someList 的前面现在代表TOS,而列表的尾部代表堆栈的末尾。因此 push/pop 将在列表的 front 添加/删除元素。

编辑:您可以实现count 方法:

  • 通过显式记住堆栈中有多少元素(即,您有一个 size 字段,每个 push() 递增,每成功 pop() 递减(即对于每个pop()size &gt; 0 然后递减size)。

  • 通过依赖用于表示堆栈的ArrayListsize() 方法。

因此可能的实现

public class Stack {
    private List<String> stack = new ArrayList<String>();

    ...        

    public int count() {
        return stack.size();
    }
 }

【讨论】:

  • 嗯,这可以工作,但我不喜欢它的 O(n) 行为。为了回答您的问题,我编辑了答案。
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 2012-09-30
  • 2011-08-13
  • 2021-11-25
  • 2018-07-17
  • 2019-11-21
  • 2015-07-30
  • 1970-01-01
相关资源
最近更新 更多