Node Stack Algorithm

The Node Stack Algorithm is a tree traversal technique that is widely used in computer science and programming for efficiently navigating through the structure of a tree, which is a popular data structure. Trees are hierarchical data structures consisting of nodes connected by edges, with each node having a single parent (except the root node) and zero or more children nodes. Tree traversal refers to the process of visiting each node of a tree and performing a specific operation or action on them. The Node Stack Algorithm is one of the well-known methods for performing the Depth-First Search (DFS) traversal, which explores the depth of each branch of the tree before backtracking. The core idea behind the Node Stack Algorithm is to use a stack data structure to keep track of the nodes to be visited during the traversal process. The stack follows a Last-In-First-Out (LIFO) approach, meaning that the last node added to the stack is the first one to be processed and removed from the stack. The algorithm begins by pushing the root node of the tree onto the stack. Then, it enters a loop where it pops the top node from the stack, processes or visits it, and then pushes its children nodes onto the stack. This process is repeated until the stack becomes empty, which indicates that all the nodes in the tree have been visited. Since the algorithm explores the children of a node before backtracking to its parent node, it effectively implements a depth-first traversal approach. This algorithm is highly efficient and can be easily implemented in various programming languages, making it a popular choice for tree traversal problems in computer science.
package DataStructures.Stacks;
/**
* Implementation of a stack using nodes.
* Unlimited size, no arraylist.
*
* @author Kyler Smith, 2017
*/


public class NodeStack<Item> {

    /**
    * Entry point for the program.
    */
    public static void main(String[] args) {
        NodeStack<Integer> Stack = new NodeStack<Integer>();

        Stack.push(3);
        Stack.push(4);
        Stack.push(5);
        System.out.println("Testing :");
        Stack.print();  			// prints : 5 4 3

        Integer x = Stack.pop(); 	// x = 5
        Stack.push(1);
        Stack.push(8);
        Integer y = Stack.peek();	// y = 8
        System.out.println("Testing :");
        Stack.print();				// prints : 8 1 4 3

        System.out.println("Testing :");
        System.out.println("x : " + x);
        System.out.println("y : " + y);
    }

    /**
    * Information each node should contain.
    * @value data : information of the value in the node
    * @value head : the head of the stack
    * @value next : the next value from this node
    * @value previous : the last value from this node
    * @value size : size of the stack
    */
    private Item data;
    private static NodeStack<?> head;
    private NodeStack<?> next;
    private NodeStack<?> previous;
    private static int size = 0;


    /**
    * Constructors for the NodeStack.
    */
    public NodeStack() {
	}

    private NodeStack(Item item) {
        this.data = item;
    }

    /**
    * Put a value onto the stack.
    *
    * @param item : value to be put on the stack.
    */
    public void push(Item item) {

    	NodeStack<Item> newNs = new NodeStack<Item>(item);

        if(this.isEmpty()) {
        	NodeStack.setHead(new NodeStack<>(item));
        	newNs.setNext(null);
        	newNs.setPrevious(null);
        } else {
        	newNs.setPrevious(NodeStack.head);
        	NodeStack.head.setNext(newNs);
        	NodeStack.head.setHead(newNs);
        }

        NodeStack.setSize(NodeStack.getSize() + 1);
    }

    /**
    * Value to be taken off the stack.
    *
    * @return item : value that is returned.
    */
    public Item pop() {

    	Item item = (Item) NodeStack.head.getData();

        NodeStack.head.setHead(NodeStack.head.getPrevious());
    	NodeStack.head.setNext(null);

    	NodeStack.setSize(NodeStack.getSize() - 1);

        return item;
    }

    /**
    * Value that is next to be taken off the stack.
    *
    * @return item : the next value that would be popped off the stack.
    */
    public Item peek() {
        return (Item) NodeStack.head.getData();
    }

    /**
    * If the stack is empty or there is a value in.
    *
    * @return boolean : whether or not the stack has anything in it.
    */
    public boolean isEmpty() {
        return NodeStack.getSize() == 0;
    }

    /**
    * Returns the size of the stack.
    *
    * @return int : number of values in the stack.
    */
    public int size() {
        return NodeStack.getSize();
    }

    /**
    * Print the contents of the stack in the following format.
    *
    * x <- head (next out)
    * y
    * z <- tail (first in)
    * .
    * .
    * .
    *
    */
    public void print() {
    	for(NodeStack<?> n = NodeStack.head; n != null; n = n.previous) {
    		System.out.println(n.getData().toString());
    	}
    }

    /** Getters and setters (private) */
    private NodeStack<?> getHead() {
    	return NodeStack.head;
    }

    private static void setHead(NodeStack<?> ns) {
    	NodeStack.head = ns;
    }

    private NodeStack<?> getNext() {
		return next;
	}

    private void setNext(NodeStack<?> next) {
		this.next = next;
	}

    private NodeStack<?> getPrevious() {
		return previous;
	}

    private void setPrevious(NodeStack<?> previous) {
		this.previous = previous;
	}

    private static int getSize() {
		return size;
	}

    private static void setSize(int size) {
		NodeStack.size = size;
	}

    private Item getData() {
		return this.data;
	}

    private void setData(Item item) {
		this.data = item;
	}
}

LANGUAGE:

DARK MODE: