HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Find minimum node in Linked-List

Submitted by: @import:stackexchange-codereview··
0
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 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 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.