使用Stack和List ADT推送方法实现

时间:2015-09-06 07:13:21

标签: java list stack adt

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

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); 
}

1 个答案:

答案 0 :(得分:3)

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

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

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

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

请注意,如果add的目的是更改当前头部(用此替换当前TOS(= Top Of Stack)),那么您可以简单地将其写为

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

我为stack ADT实施了String。我将其留作一个简单的练习,根据您的需要进行更改(使用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,列表的尾部代表堆栈的结尾。因此,推/弹将在列表的前面处添加/删除元素。

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

  • 通过明确记住堆栈中有多少元素(即,您有size字段,每个push()递增一次,每成功递减 { {1}}(即pop()时每pop()size > 0然后递减size)。

  • 依靠用于表示堆栈的size()的{​​{1}}方法。

因此可能实施

ArrayList