patternjavaMinor
Find minimum node in Linked-List
Viewed 0 times
nodeminimumfindlistlinked
Problem
I wrote a method that will return the minimum element in a linked-list that operates in O(1) time. I tested and everything works fine. However, I was wondering if there is anything that I can do to make my code more efficient or cleaner.
```
public class MinElementInStack {
static Node stack;
static Node minStack;
public void push(int data) {
// push nodes into stack
Node last = new Node(data);
last.next = stack;
stack = last;
// check if node being pushed is new min
// if it is then push into minStack
if(minStack == null) { // for first node
Node toBePushed = new Node(data);
toBePushed.next = minStack;
minStack = toBePushed;
} else { // if int to be pushed is less than current min on stack
// then push it onto the stack, otherwise push the same min value from previous
int toBePushedInt = data;
if(toBePushedInt < (Integer)minStack.item) {
Node toBePushed = new Node(data);
toBePushed.next = minStack;
minStack = toBePushed;
} else {
Node toBePushed = new Node((Integer)minStack.item);
toBePushed.next = minStack;
minStack = toBePushed;
}
}
}
public void pop() {
if (stack != null && minStack != null) {
stack = stack.next;
minStack = minStack.next;
}
}
public int min() {
int min = (int) minStack.item;
return min;
}
public void print(Node node) {
Node temp = node;
while (temp != null) {
System.out.println(temp.item);
temp = temp.next;
}
}
public static void m
public class Node {
//private Object item;
Node next;
Object item;
// constructor
public Node(Object item) {
this.item = item;
next = null;
}
}```
public class MinElementInStack {
static Node stack;
static Node minStack;
public void push(int data) {
// push nodes into stack
Node last = new Node(data);
last.next = stack;
stack = last;
// check if node being pushed is new min
// if it is then push into minStack
if(minStack == null) { // for first node
Node toBePushed = new Node(data);
toBePushed.next = minStack;
minStack = toBePushed;
} else { // if int to be pushed is less than current min on stack
// then push it onto the stack, otherwise push the same min value from previous
int toBePushedInt = data;
if(toBePushedInt < (Integer)minStack.item) {
Node toBePushed = new Node(data);
toBePushed.next = minStack;
minStack = toBePushed;
} else {
Node toBePushed = new Node((Integer)minStack.item);
toBePushed.next = minStack;
minStack = toBePushed;
}
}
}
public void pop() {
if (stack != null && minStack != null) {
stack = stack.next;
minStack = minStack.next;
}
}
public int min() {
int min = (int) minStack.item;
return min;
}
public void print(Node node) {
Node temp = node;
while (temp != null) {
System.out.println(temp.item);
temp = temp.next;
}
}
public static void m
Solution
-
Since your
-
Since we are dealing with a stack of (primitive) integers, I would rename
-
Next, why not rename
-
Both the fields in
-
You could define
-
-
Both
-
I would add the field
-
Instead of
-
You are overkilling it in the
Summa summarum
All in all, I had this in mind:
Hope that helps.
Since your
min() in your implementation returns an int, I would modify the type of Node.item to int.-
Since we are dealing with a stack of (primitive) integers, I would rename
MinElementInStack to IntStack.-
Next, why not rename
Node to IntStackNode?-
Both the fields in
Node can be specified as private final + you could add getters for the two fields.-
You could define
Node as an inner static class in your actual stack class.-
pop() should return the integer datum associated with the popped node.-
Both
pop() and min() should throw EmptyStackException whenever the stack is empty.-
I would add the field
size to the stack, and the methods size() and isEmpty() which rely on the field size.-
Instead of
print(), I would override public String toString().-
You are overkilling it in the
push, mainly due to the fact that you create the new node more than once, and rename data to toBePushedInt.Summa summarum
All in all, I had this in mind:
import java.util.EmptyStackException;
import java.util.Scanner;
public class IntStack {
private static final String STRING_BEGIN = "[";
private static final String STRING_END = "]";
private static final String SEPARATOR = ", ";
private static final class IntStackNode {
private final int datum;
private final IntStackNode previous;
private IntStackNode previousMinimum;
IntStackNode(final int datum, final IntStackNode previous) {
this.datum = datum;
this.previous = previous;
}
int getDatum() {
return datum;
}
IntStackNode getPreviousNode() {
return previous;
}
IntStackNode getPreviousMinimum() {
return previousMinimum;
}
void setPreviousMinimum(final IntStackNode previousMinimum) {
this.previousMinimum = previousMinimum;
}
}
private IntStackNode top;
private IntStackNode minimum;
private int size;
public void push(final int datum) {
IntStackNode newnode = new IntStackNode(datum, top);
if (isEmpty()) {
minimum = newnode;
} else if (minimum.getDatum() > datum) {
newnode.setPreviousMinimum(minimum);
minimum = newnode;
}
top = newnode;
++size;
}
public int pop() {
if (top == null) {
throw new EmptyStackException();
}
final IntStackNode ret = top;
if (minimum == ret) {
minimum = ret.getPreviousMinimum();
}
top = top.getPreviousNode();
--size;
return ret.datum;
}
public int min() {
if (isEmpty()) {
throw new EmptyStackException();
}
return minimum.getDatum();
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString() {
IntStackNode node = top;
if (top == null) {
return STRING_BEGIN + STRING_END;
}
final StringBuilder sb = new StringBuilder(STRING_BEGIN);
sb.append(top.getDatum());
node = top.getPreviousNode();
for (int i = 1; i ");
final String command = scanner.next().trim().toLowerCase();
switch (command) {
case "push":
doPush(stack, scanner);
break;
case "pop":
doPop(stack);
break;
case "print":
System.out.println(stack);
break;
case "min":
doMin(stack);
break;
case "quit":
case "exit":
break loop;
default:
System.out.println("Unknown command: \"" + command + "\"");
}
}
}
private static void doPush(IntStack stack, Scanner scanner) {
int datum;
try {
datum = scanner.nextInt();
} catch (NumberFormatException ex) {
System.out.println("ERROR: An integer is required.");
return;
}
stack.push(datum);
}
private static void doPop(IntStack stack) {
try {
stack.pop();
} catch (EmptyStackException ex) {
System.out.println("ERROR: Popping from an empty stack.");
}
}
private static void doMin(IntStack stack) {
try {
System.out.println(stack.min());
} catch (EmptyStackException ex) {
System.out.println(
"ERROR: Asking for minimum element from an empty stack.");
}
}
}Hope that helps.
Code Snippets
import java.util.EmptyStackException;
import java.util.Scanner;
public class IntStack {
private static final String STRING_BEGIN = "[";
private static final String STRING_END = "]";
private static final String SEPARATOR = ", ";
private static final class IntStackNode {
private final int datum;
private final IntStackNode previous;
private IntStackNode previousMinimum;
IntStackNode(final int datum, final IntStackNode previous) {
this.datum = datum;
this.previous = previous;
}
int getDatum() {
return datum;
}
IntStackNode getPreviousNode() {
return previous;
}
IntStackNode getPreviousMinimum() {
return previousMinimum;
}
void setPreviousMinimum(final IntStackNode previousMinimum) {
this.previousMinimum = previousMinimum;
}
}
private IntStackNode top;
private IntStackNode minimum;
private int size;
public void push(final int datum) {
IntStackNode newnode = new IntStackNode(datum, top);
if (isEmpty()) {
minimum = newnode;
} else if (minimum.getDatum() > datum) {
newnode.setPreviousMinimum(minimum);
minimum = newnode;
}
top = newnode;
++size;
}
public int pop() {
if (top == null) {
throw new EmptyStackException();
}
final IntStackNode ret = top;
if (minimum == ret) {
minimum = ret.getPreviousMinimum();
}
top = top.getPreviousNode();
--size;
return ret.datum;
}
public int min() {
if (isEmpty()) {
throw new EmptyStackException();
}
return minimum.getDatum();
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
@Override
public String toString() {
IntStackNode node = top;
if (top == null) {
return STRING_BEGIN + STRING_END;
}
final StringBuilder sb = new StringBuilder(STRING_BEGIN);
sb.append(top.getDatum());
node = top.getPreviousNode();
for (int i = 1; i < size; ++i) {
sb.append(SEPARATOR).append(node.getDatum());
node = node.getPreviousNode();
}
return sb.append(STRING_END).toString();
}
public static void main(final String[] args) {
final IntStack stack = new IntStack();
final Scanner scanner = new Scanner(System.in);
loop:
while (true) {
System.out.print("> ");
final String command = scanner.next().trim().toLowerCase();
switch (command) {
case "push":
doPush(stack, scanner);
break;
case "pop":
doPop(stack);
break;
Context
StackExchange Code Review Q#126398, answer score: 4
Revisions (0)
No revisions yet.