为堆栈正确编写 java 中的面向对象代码
Properly Writing Object Oriented Code in java for a stack
我正在尝试以面向对象的方式编写代码。在这种特殊情况下,我想在 O(1) 时间内跟踪堆栈的最小值。我知道怎么做,它的想法,我的想法,就是有另一个堆栈来跟踪每次推送和弹出的最小值。
我已经将每个 class 嵌套在程序 class 中,它被称为 minStack,这似乎不是正确的做法但是,当我创建 minStack 的实例并调用其变量时,它对于常规堆栈来说效果很好。我创建了一个 class extends a Stack called StackWithMin 但我不知道如何调用它的值。我应该创建一个 StackWithMin 的新实例吗?如果是这样我该怎么做?我在 main 函数上面的代码末尾做了它,但是 peek() 总是 returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
我建议像这样创建通用接口Stack
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs
detectable at compile time.
查看有关泛型的更多信息here。
然后用通用的方式实现这个接口。所有实现细节都将隐藏在此 class 中(例如您的 Node
class)。这是代码(它只是为了展示这个想法,如果你想使用它你需要通过异常处理来改进它)。请注意 class Node
现在也是通用的。
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
现在我们进入存储最小值的部分。我们可以扩展 SimpleStack
class 并使用另一个 SimpleStack
添加字段。但是我认为最好再实现 Stack
并为值和最小值存储两个堆栈。示例如下。我已经概括了现在使用 Comparator
比较对象的 class,因此您可以使用任何其他对象类型。
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
现在您可以像这样使用这两种实现方式
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1
我正在尝试以面向对象的方式编写代码。在这种特殊情况下,我想在 O(1) 时间内跟踪堆栈的最小值。我知道怎么做,它的想法,我的想法,就是有另一个堆栈来跟踪每次推送和弹出的最小值。
我已经将每个 class 嵌套在程序 class 中,它被称为 minStack,这似乎不是正确的做法但是,当我创建 minStack 的实例并调用其变量时,它对于常规堆栈来说效果很好。我创建了一个 class extends a Stack called StackWithMin 但我不知道如何调用它的值。我应该创建一个 StackWithMin 的新实例吗?如果是这样我该怎么做?我在 main 函数上面的代码末尾做了它,但是 peek() 总是 returns null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
我建议像这样创建通用接口Stack
interface Stack<T> {
void push(T item);
T pop();
T peek();
}
Generics add stability to your code by making more of your bugs detectable at compile time.
查看有关泛型的更多信息here。
然后用通用的方式实现这个接口。所有实现细节都将隐藏在此 class 中(例如您的 Node
class)。这是代码(它只是为了展示这个想法,如果你想使用它你需要通过异常处理来改进它)。请注意 class Node
现在也是通用的。
class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
现在我们进入存储最小值的部分。我们可以扩展 SimpleStack
class 并使用另一个 SimpleStack
添加字段。但是我认为最好再实现 Stack
并为值和最小值存储两个堆栈。示例如下。我已经概括了现在使用 Comparator
比较对象的 class,因此您可以使用任何其他对象类型。
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}
现在您可以像这样使用这两种实现方式
SimpleStack<Integer> s1 = new SimpleStack<>();
s1.push(1);
s1.push(2);
s1.push(3);
System.out.println(s1.pop()); // print 3
System.out.println(s1.pop()); // print 2
System.out.println(s1.pop()); // print 1
StackWithComparator<Integer> s2 = new StackWithComparator<>(new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
});
s2.push(1);
s2.push(2);
s2.push(3);
s2.push(0);
s2.push(4);
System.out.println(s2.min() + " " + s2.pop()); // print 0 4
System.out.println(s2.min() + " " + s2.pop()); // print 0 0
System.out.println(s2.min() + " " + s2.pop()); // print 1 3
System.out.println(s2.min() + " " + s2.pop()); // print 1 2
System.out.println(s2.min() + " " + s2.pop()); // print 1 1