我有从"A"到"C"的三本书。我如何使用Stack
显示它们,然后显示其大小。另外,我如何删除书"B",然后能够再次显示大小?
这是我到目前为止的代码:
import java.util.*;
public class test_stack {
public static void main (String[] args){
Stack<String> stack = new Stack<String>();
stack.push(“a”);
printStack(stack);
stack.push(“b”);
printStack(stack);
stack.push(“c”);
printStack(stack);
stack.pop();
printStack(stack);
stack.pop();
printStack(stack);
stack.pop();
printStack(stack);
}
private static void printStack(Stack<String> s){
if(s.isEmpty())
System.out.printIn(“empty stack”);
else
System.out.printf(“% s TOPn”, s);
}
}
我得到的输出是:
[a] TOP
[a, b] TOP
[a, b, c] TOP
[a, b] TOP
[a] TOP
empty stack
我想实现:
[a,b,c] TOP
[a,c] TOP
empty stack
如果你想从中间删除,我建议你使用不同的数据结构,如linked list
,因为这就是linked lists
的作用。如果需要从中间删除一个元素,你根本不应该使用堆栈。但既然问题要求这样做,那么您可以引入deleteFrom()
方法,如下所示。
该方法将接受两个参数,堆栈和要删除的对象,如果该对象存在于堆栈中,则该对象将被删除。
[a] TOP
[a, b] TOP
[a, b, c] TOP
After calling deleteFrom(stack, "b")
[a, c] TOP
deleteFrom()方法代码:
public static Stack<String> deleteFrom(Stack<String> stack, String obj) {
if (stack.search(obj) == -1) {
System.out.println("Element doesn't exists in stack.");
return stack;
}
Stack<String> stack2 = new Stack<String>();
while (stack.search(obj) != -1)
stack2.push(stack.pop());
stack2.pop();
while (stack2.size() != 0)
stack.push(stack2.pop());
return stack;
}
最终代码看起来像:
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
Stack<String> stack = new Stack<String>();
stack.push("a");
printStack(stack);
stack.push("b");
printStack(stack);
stack.push("c");
printStack(stack);
stack = deleteFrom(stack, "b");
System.out.println("After calling deleteFrom(stack, "b")");
printStack(stack);
}
private static void printStack(Stack<String> s) {
if (s.isEmpty()) {
System.out.println("empty stack");
} else {
System.out.printf("%s TOPn", s);
}
}
public static Stack<String> deleteFrom(Stack<String> stack, String obj) {
if (stack.search(obj) == -1) {
System.out.println("Element doesn't exists in stack.");
return stack;
}
Stack<String> stack2 = new Stack<String>();
while (stack.search(obj) != -1)
stack2.push(stack.pop());
stack2.pop();
while (stack2.size() != 0)
stack.push(stack2.pop());
return stack;
}
}
不能使用Stack
,因为这违反了Stack
操作的整个概念。即使我们想出了一个函数,可以从堆栈中间删除一个元素,那么在幕后,它将删除所有上述元素>删除所需元素>再次推回上述元素。这绝对不是一个好方法。
stack使用的概念是不同的。但是如果你有一个场景,你必须从中间删除一个元素,那么你应该使用LinkedList
而不是Stack
。这就是LinkedList
的作用
package com.tutorialspoint;
import java.util.*;
public class LinkedListDemo {
public static void main(String[] args) {
// create a LinkedList
LinkedList list = new LinkedList();
// add some elements
list.add("A");
list.add("B");
list.add("C");
// print the list
System.out.println("LinkedList:" + list);
System.out.println("size:" + list.size());
// remove "B" Element from the list
list.remove("B");
// print the list
System.out.println("LinkedList:" + list);
System.out.println("size:" + list.size());
}
}
LinkedList:[A, B, C]
size: 3
LinkedList:[A, C]
size: 2
我不认为这可以通过push和pop的一般堆栈操作来完成。记住堆栈是后进先出的。所以为了移除(POP) b,你必须移除(POP) c,然后你必须再次按压c。
编辑:如果您设法完成了所需的目标,请放心,您没有使用堆栈的概念。编码快乐! !:)
为了从你的堆栈中移除b
,你需要将所有的书从堆栈中弹出并将它们推入临时堆栈,直到你到达b
,然后将所有的书从临时堆栈中弹出并将它们推回主堆栈。
import java.util.*;
public class test_stack {
public static void main (String[] args){
// put a, b and c on the stack
Stack<String> stack = new Stack<String>();
stack.push(“a”);
stack.push(“b”);
stack.push(“c”);
printStack(stack);
// pop items off the stack until we reach b (and push non b items onto temporary stack)
Stack<String> temporaryStack = new Stack<String>();
String currentItem;
do {
currentItem = stack.pop();
if(!currentItem.equals("b")) {
temporaryStack.push(currentItem);
} while(!currentItem.equals("b"));
// push temporary stack back onto main stack
while(!temporaryStack.isEmpty()) {
stack.push(temporaryStack.pop());
}
printStack(stack);
}
private static void printStack(Stack<String> s){
if(s.isEmpty())
System.out.printIn(“empty stack”);
else
System.out.printf(“% s TOPn”, s);
}
}
这是Stack
使用LinkedList
使用适配器设计模式的实现,您必须在头部或尾部同时push/pop以获得Stack
public class StackLL<E> {
private LinkedList<E> list;
public StackLL() {
list = new LinkedList<>();
}
public void push(E e) {
list.addFirst(e);
}
public E pop(E e) {
Iterator<E> it = list.descendingIterator(); // list.iterator()
while (it.hasNext()) {
E ele = it.next();
if (ele == e) {
it.remove();
break;
}
}
return null;
}
public E pop() {
return list.removeFirst();
}
public int size() {
return list.size();
}
public void print() {
System.out.println(list);
}
}
在这个实现中,底层数据结构仍然是一个双链表,所以你可以用你的自定义方法来做一些特殊的操作,在你的例子中,它是搜索和删除一个元素,所以我重载了pop方法与一个要删除的元素,它做一个迭代,删除匹配的一个元素,否则返回null。
public static void main(String[] args) {
StackLL<String> stack = new StackLL<>();
stack.push("a");
stack.push("b");
stack.push("c");
stack.print();
stack.pop("b");
stack.print();
stack.pop("b");
}
输出[c, b, a]
[c, a]
如果你想删除中间元素,你可以简单地将element作为成员变量,在每2次push之后,你可以增加一个位置,也在每2次pop之后,你可以减少一个位置,复杂度为0(1)。
您可以创建第二个临时堆栈来保存您想要删除的元素上方的值:
Stack<String> stack = new Stack<String>();
stack.push("a");
stack.push("b");
stack.push("c");
// Pop the elements from the original stack onto
// the temporary stack.
Stack<String> temp = new Stack<String>();
while (!stack.isEmpty()) {
String top = stack.pop();
if (top.equals("b")) {
break;
}
temp.push(top);
}
// Pop the elements from the temporary stack
// back into the original stack. This preserves
// the original order.
while (!temp.isEmpty()) {
stack.push(temp.pop());
}