How to use generic in Stack data structure? - java

I have implemented a simple Stack in Java and it works. It uses Node class for holding the stack int values. Now, I'm planning another class NodeWithMin that should contain the node in concern and the minimum values from the node to bottom. That means when I will get the top node of the stack I will have node and the minimum value of the stack.
I want to use generic with the Stack class to switch whichever class ( Node / NodeWithMin) that I would like to plug with it. So, finally it will be something -
public class myStack extends Stack< Node or NodeWithMin >{
}
Where Stack needs to be
class Stack<T>{
}
Let me know if you need further clarification of the question. I understand inside of some methods in the Stack class needs to changed. Any advice on how can I do that ? THANK YOU.
import java.util.*;
class Node {
public Node above;
public Node below;
public int data;
public Node(int data) {
this.data = data;
}
}
class NodeWithMin {
public NodeWithMin above;
public NodeWithMin below;
public int data;
public int min;
public NodeWithMin(int data , int min){
this.data = data;
this.min = min;
}
}
class Stack {
private int capacity;
public Node top;
public Node bottom;
public int size;
HashSet<Integer> hashSet = new HashSet<Integer>();
public Stack ( int cap ){
this.top = null;
this.bottom = null;
this.capacity = cap;
this.size = 0;
}
public static int randomInt(int n) {
return (int) (Math.random() * n);
}
public static int randomIntInRange(int min, int max) {
return randomInt(max + 1 - min) + min;
}
public boolean isFull() {
return capacity == size;
}
public void join (Node newNode, Node stackTop) {
// not empty stack
if ( stackTop != null ){
stackTop.above = newNode;
}
// if the new node is not null
// previous top is now below of the inserted node which is the current top
if ( newNode != null){
newNode.below = stackTop;
}
}
public boolean push(int v) {
if (size >= capacity)
return false;
size++;
Node n = new Node(v);
if (size == 1) bottom = n;
join(n, top);
// define the new top
top = n;
// pushing is sucessful
return true;
}
public int min(){
if ( top == null) return -1;
Node curr = this.top;
int min =-1 ;
System.out.println("\n\n");
while( curr != null){
hashSet.add(curr.data);
curr = curr.below;
}
System.out.println();
min = Collections.min(hashSet);
return min;
}
public int pop() {
Node t = top;
top = top.below;
size--;
return t.data;
}
public int peek (){
Stack myStack = this;
return myStack.top.data ;
}
public boolean isEmpty() {
return size == 0;
}
public int removeBottom() {
Node b = bottom;
bottom = bottom.above;
if (bottom != null) bottom.below = null;
size--;
return b.data;
}
public void display(){
if ( top == null) return;
Node curr = this.top;
int min =-1 ;
System.out.println("\n\n");
while( curr != null){
System.out.println( curr.data);
curr = curr.below;
if ( curr != null){
System.out.println("↑");
}
}
System.out.println();
}
public static void main ( String[] args ){
// System.out.println("\nMy stack is here \n");
Stack s = new Stack(5);
for (int j = 0; j < 5; j ++){
s.push( randomIntInRange(0, 100) );
}
s.display();
System.out.println("the min of the stack is = "+ s.min());
}
}

It looks to me as if NodeWithMin does the same basic thing as Node, plus it has the Min stuff. So I'd make NodeWithMin extend Node. Then you could declare MyStack as:
public class myStack extends Stack< ? extends Node > {
...
}
MyStack will now work with either Node or NodeWithMin.
As for Stack, the most notable problem is that it is written to explicitly depend on instances of Node. That's an issue because you say you want Stack to be generic, able to take any T. So you'll have to keep all of the T instances in the correct order without expecting them to remember who comes before or after, and that's inconsistent with what you're trying to do with NodeWithMin.
So I think you need to rethink just how generic you want this stuff to be. If Stack should really be completely generic, i.e. it should be able to keep any kind of object in LIFO order, then MyStack will have to override large portions of the methods in Stack in order to make use of what it knows about Node. OTOH, if all you really want to do is keep a bunch of Node (or subtypes thereof) objects in LIFO order, then ditch Stack completely and just go straight to MyStack.
Oh BTW, your use of HashSet is troublesome. Since you instantiate it once, you run the risk of it keeping stuff around that no longer exists in the Stack, i.e. you could pop the current min, but the min() method would keep returning it. Better to make it a local variable in the min() method since that's the only place it's used.
Further, in order to use the Collections.min() method, all of the objects in the Stack must implement Comparable, and that argues against using a generic T. You will probably want to move the min() method to MyStack (assuming that you change Node to implement Comparable).

Related

Stack Implementation with getMiddle and getAt functions

I need to create data structure acting like stack (LIFO) with these functions: init(), push(Object), pop(), getMiddle(), getAt(k).
All of the fucntion except getAt() should be with complexity O(1), and getAt(k) with time complexity O(log(k)). Space Complexity should be O(n)
The problem is getAt(k) function, when k is index of k'th inserted (accoriding to inserting order) element in the stack.
I decided to go with DoublyLinkedList because then I'll can to move pointer to the middle element. I also share a code. If someone has any suggestions about how I can even get O(k) complexity or even the solution.
class Node {
Node prev;
Node next;
Object data;
int order; //index of inserted element
Node(Object data, int order) {
prev = null;
next = null;
this.data = data;
this.order = order;
}
}
public class LikeStack {
Node head;
Node mid;
int size;
//constructor
public LikeStack() {
this.size = 0;
this.head = null;
this.mid = null;
}
//push object to the stack and move the pointer to the middle of the stack if needed
public void push(Object o) {
size++;
Node toPush = new Node(o, size);
toPush.prev = null;
toPush.next = head;
if (size == 1) {
mid = toPush;
} else {
head.prev = toPush;
{
if (size % 2 == 1) {
mid = mid.prev;
}
}
}
head = toPush;
}
//pop object from the stack and move the pointer to the middle of the stack if needed
public Object pop() throws Exception {
if(size<=0)
{
throw new Exception("The stack is empty");
}
size--;
Object temp = head.data;
head=head.next;
if(head!=null)
{
head.prev=null;
}
if(size%2==1)
{
mid=mid.next;
}
return temp;
}
//just returning the middle element
public Object getMiddle(){
return mid.data;
}
First is to maintain an index variable, say index to 0.
When you do the push(), you will add the element to the map like:
void push(int value){
// your code
map.put(index++,your_node);
}
In your pop(), you would do
int pop(){
// your code
your_node.prev.next = null;
map.remove(index--);
}
So, getting the middle element will just be a lookup in the map
int middle(){
// your code
return map.get(index / 2).value;
}
Getting the value at k will be similar to the above:
int getKthElement(int K){
// your code
return map.get(K-1).value; // If K is above index, you can throw an exception
}

How to return the number of elements in a linkedlist

I need to implement the size() function so that it will count the number of elements in a list.
I cannot use a count variable. Should work (given our 'top' node and the constructors [default] setup). I know i have to use a loop but i don't know how to reference indices like i do with arrays.
public class DropOutStack<T> implements StackADT<T> {
private int max;
private LinearNode<T> top;
public DropOutStack(){
max = 10;
top = null;
}
public DropOutStack(int capacity){
setMaxSize(capacity);
}
public DropOutStack(T element){
LinearNode<T> temp = newLinearNode(element);
temp.setNext(top);
top = temp;
max = 10;
}
public DropOutStack(T element, int capacity){
LinearNode<T> temp = newLinearNode(element);
temp.setNext(top);
top = temp;
setMaxSize(capacity);
}
public int size(){
}
public boolean isEmpty(){
if(top == null) return true;
return false;
}
}
DropOutStack list = new DropOutStack("T",4);
System.out.print(list.size());
Should print 1. Since only "T" has been added.
Adding a screenshot of the composition class. I think I have to use a method from there. Interface just declares the push pop peek isempty functions. No code. Not needed for the size() function I believe. This is my first programming class so I hope I gave everything needed to solve this. Please help enter image description here
Something like that will count the elements:
ToIntFunction<LinearNode<T>> counter = (node) -> {
int count = 0;
while( node != null ) {
count++;
node = node.getNext();
}
return( count );
};
…applied in the DropOutStack class size() function:
public int size() {
return( counter.applyAsInt( top ) );
}

Copy Elements From Stack to Queue

I'm supposed to copy elements from a stack to a queue.
I haven't been able to think of a way to keep the stack the way it is and still copy its elements to a queue.
I ended up with this method which removes the elements completely from the stack and adds them to the queue:
public void CopyFromStack(){
E t;
int c = w.size();
while(c != 0){
t = w.pop();
enqueue(t);
c--; }}
Trying to push elements back is not an option because it'll do it backwards.
Edit: This is the class that contains my method which is my queue class:
public class Queue<E> {
protected int size;
protected Node<E> head;
protected Node<E> tail;
NodeStack<E> w = new NodeStack<E>();
NodeStack<E> w2 = new NodeStack<E>();
public Queue(){
size = 0;
head = tail = null;}
public boolean isEmpty(){
return size==0;}
public void enqueue(E elem) {
Node<E> node = new Node<E>();
node.setElement(elem);
node.setNext(null);
if (size == 0) head = node;
else tail.setNext(node);
tail = node;
size++; }
public E dequeue() {
if (size == 0) System.out.print("Queue is empty.");
E tmp = head.getElement();
head = head.getNext();
size--;
if (size == 0) tail = null;
return tmp; }
public String toString(){
String s = "";
E t;
int c = size;
while(c != 0){
t = dequeue();
s += t + " ";
enqueue(t);
c--; }
return s;}
public int FindItem(E elem){
int index=0;
int c = size;
E t;
while(c != 0){
t = dequeue();
if (t == elem)
return index;
else index++;
c--;}
System.out.print("Not found!");
return -1;}
public void CopyToStack(){
System.out.print("Elements copied to the stack are: ");
E t;
int c = size;
while(c != 0){
t = dequeue();
w.push(t);
enqueue(t);
c--;
System.out.print(w.pop()+" "); }}
public void CopyFromStack(){
E t;
int c = w.size();
while(c != 0){
t = w.pop();
enqueue(t);
c--; }}
Q: I haven't been able to think of a way to keep the stack the way it is A:
A: That's because reading from a "classic" stack is destructive. "Reading" an element == removing that element from the stack.
TWO SOLUTIONS:
1) Modify your stack implementation so that you can "peek" each element
... or ...
2) Create a new stack containing all the elements from the first one.
Q: I ended up with this method ... Trying to push elements back is not an option because it'll do it backwards.
"A: This is a variation on "Option 2): above.
SOLUTION: Just create a new stack object, and push each element at the same time as you enqueue the element.
PS:
The standard JRE implementation of Stack includes peek() and search() methods. But I don't think they would help you here. If you wanted "Option 1)", you'd have to implement your own, custom stack.
================== UPDATE ==================
Note, too:
You should always indent your methods, and indent your "if" and "loop" blocks within your methods.
You should use "camel-case" (lower-case first letter) for your method names.
Here are the "official" Java coding conventions. They were useful in 1995; they're useful today:
http://www.oracle.com/technetwork/java/index-135089.html
There's actually a third option: Java's "Stack" happens to implement "iterator". Here's an example:
EXAMPLE CODE:
package com.testcopy;
import java.util.ArrayDeque;
import java.util.Iterator;
import java.util.Queue;
import java.util.Stack;
public class TestCopy {
public static void main (String[] args) {
TestCopy app = new TestCopy ();
app.run ();
}
public void run () {
// Create and populate stack
Stack<String> myStack = new Stack<String> ();
mkData(myStack);
// Copy to queue
Queue<String> myQueue = new ArrayDeque<String> ();
copyFromStack (myStack, myQueue);
// Print
int i=0;
for (String s : myQueue) {
System.out.println ("myQueue[" + i++ + "]: " + s);
}
}
#SuppressWarnings("unchecked")
public void mkData (Stack stack) {
stack.push("A");
stack.push("B");
stack.push("C");
// Stack should now contain C, B, A
}
public void copyFromStack (Stack stack, Queue queue) {
#SuppressWarnings("rawtypes")
Iterator it = stack.iterator ();
while (it.hasNext()) {
queue.add(it.next());
}
}
}
EXAMPLE OUTPUT:
myQueue[0]: A
myQueue[1]: B
myQueue[2]: C

Implement a Stack with a circular singly linked list

I'm trying to implement the a Stack in Java with a circular singly linked list as the underlying data structure. I placed the insert function for a circular linked list in replacement of the push function for the stack and so on. I don't have any errors but I'm having troubles displaying the stack. If anyone could point me in the right direction of how to display the stack or what's going wrong I'd really appreciate it!
Here is my stack class:
public class Stack {
private int maxSize; // size of stack array
private long[] stackArray;
private int top; // top of stack
private Node current = null; // reference to current node
private int count = 0; // # of nodes on list
private long iData;
public Stack(int s) // constructor
{
maxSize = s; // set array size
stackArray = new long[maxSize]; // create array
top = -1; // no items yet
}
public void push(long j) // put item on top of stack
{
Node n = new Node(j);
if(isEmpty()){
current = n;
}
n.next = current;
current = n;
count++;
}
//--------------------------------------------------------------
public Node pop() // take item from top of stack
{
if(isEmpty()) {
return null;
}
else if(count == 1){
current.next = null;
current = null;
count--;
return null;
}else{
Node temp = current;
current = current.next;
temp.next = null;
temp = null;
count--;
}
return current;
}
//--------------------------------------------------------------
public Node peek(long key) // peek at top of stack
{
Node head = current;
while(head.iData != key){
head = head.next;
}
return head;
}
//--------------------------------------------------------------
public boolean isEmpty() // true if stack is empty
{
return (count == 0);
}
//--------------------------------------------------------------
public boolean isFull() // true if stack is full
{
return (count == maxSize-1);
}
//--------------------------------------------------------------
Here is my constructor class
public class Node{
public long iData; // data item (key)
public Node next; // next node in the list
public Node(long id){ // constructor
iData = id; // next automatically nulls
}
public void displayNode(){
System.out.print(iData + " ");
}
public static void main(String[] args) {
Stack newlist = new Stack(3);
newlist.push(1);
newlist.push(2);
newlist.push(3);
newlist.push(4);
newlist.pop();
newlist.pop();
newlist.push(4);
newlist.pop();
newlist.peek(1);
newlist.push(5);
while( !newlist.isEmpty() ) // until it’s empty,
{ // delete item from stack
Node value = newlist.pop();
System.out.print(value); // display it
System.out.print(" ");
} // end while
System.out.println("");
}
//newlist.displayList();
}
First, in your main function you are printing value using System.out.print function. This displays the object's class name representation, then "#" followed by its hashcode.
Replace following lines
System.out.print(value); // display it
System.out.print(" ");
with
value.displayNode();
Second, in pop method, you are returning null when count is 1. It should return the last element which is present in the list. Also, in last else if clause, you should return temp. Replace your code with this.
public Node pop() // take item from top of stack
{
if (isEmpty()) {
return null;
}
Node temp = current;
if (count == 1) {
current = null;
} else {
current = current.next;
}
count--;
temp.next = null;
return temp;
}
A few notes on your implementation:
1) stackArray member seems to be a leftover from another array based stack implementation.
2) is max size really a requirement? if so, you don't enforce the stack size limitation in push(..)
3) Your push(..) method doesn't keep the list circular. You should close the loop back to the new node.
4) Adding a dummy node allows you to keep the linked list circular, regardless of the stack size. This can make your push(..) method simpler (as well as any iteration for printing purposes for example)
5) The peek() method contract is unclear. Usually you want the peek method to return the value in the top of the stack, without removing it. Also, why do you return type Node? This class should be hidden from the caller - it's an internal implementation detail, not something you want to expose in your API.
Following is an alternative implementation, that also supports toString():
public class Stack {
private Node EOS;
private int count = 0;
public Stack() {
EOS = new Node(0);
EOS.next = EOS;
}
public void push(long j) {
Node newNode = new Node(j);
Node tmp = EOS.next;
EOS.next = newNode;
newNode.next = tmp;
count++;
}
public Long pop() {
if (isEmpty()) {
return null;
} else {
count--;
Node node = EOS.next;
EOS.next = node.next;
return node.iData;
}
}
public Long peek() {
if (isEmpty()) {
return null;
} else {
Node node = EOS.next;
return node.iData;
}
}
public boolean isEmpty() {
return (count == 0);
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node p = EOS.next;
while (p != EOS) {
sb.append(p).append("\n");
p = p.next;
}
return sb.toString();
}
private static class Node {
public long iData;
public Node next;
public Node(long id) {
iData = id;
}
#Override
public String toString() {
return "<" + iData + ">";
}
}
}

Is it possible to implement an algorithm to find the nth to last element of a singly linked list using recursion in java

I know that you can simply solve this question iteratively by using a counter to increment each time you pass a node in linkedlist; also creating an arraylist and setting the data found with each node inside it. Once you hit the tail of the linkedlist, just minus the Nth term from the total number of elements in the arraylist and you will be able to return the answer. However how would someone perform this using recursion? Is it possible and if so please show the code to show your genius :).
Note: I know you cannot return two values in Java (but in C/C++, you can play with pointers :])
Edit: This was a simple question I found online but I added the recursion piece to make it a challenge for myself which I've come to find out that it may be impossible with Java.
The trick is to do the work after the recursion. The array in the private method is basically used as a reference to a mutable integer.
class Node {
Node next;
int data;
public Node findNthFromLast(int n) {
return findNthFromLast(new int[] {n});
}
private Node findNthFromLast(int[] r) {
Node result = next == null ? null : next.findNthFromLast(r);
return r[0]-- == 0 ? this : result;
}
}
As a general rule, anything that can be done with loops can also be done with recursion in any reasonable language. The elegance of the solution may be wildly different. Here is a fairly java idiomatic version. I've omitted the usual accessor functions for brevity.
The idea here is to recur to the end of the list and increment a counter as the recursion unwinds. When the counter reaches the desire value, return that node. Otherwise return null. The non-null value is just returned all the way tot the top. Once down the list, once up. Minimal arguments. No disrespect to Adam intended, but I think this is rather simpler.
NB: OP's statement about Java being able to return only one value is true, but since that value can be any object, you can return an object with fields or array elements as you choose. That wasn't needed here, however.
public class Test {
public void run() {
Node node = null;
// Build a list of 10 nodes. The last is #1
for (int i = 1; i <= 10; i++) {
node = new Node(i, node);
}
// Print from 1st last to 10th last.
for (int i = 1; i <= 10; i++) {
System.out.println(i + "th last node=" + node.nThFromLast(i).data);
}
}
public static void main(String[] args) {
new Test().run();
}
}
class Node {
int data; // Node data
Node next; // Next node or null if this is last
Node(int data, Node next) {
this.data = data;
this.next = next;
}
// A context for finding nth last list element.
private static class NthLastFinder {
int n, fromLast = 1;
NthLastFinder(int n) {
this.n = n;
}
Node find(Node node) {
if (node.next != null) {
Node rtn = find(node.next);
if (rtn != null) {
return rtn;
}
fromLast++;
}
return fromLast == n ? node : null;
}
}
Node nThFromLast(int n) {
return new NthLastFinder(n).find(this);
}
}
Okay, I think think this should do the trick. This is in C++ but it should be easy to translate to Java. I also haven't tested.
Node *NToLastHelper(Node *behind, Node *current, int n) {
// If n is not yet 0, keep advancing the current node
// to get it n "ahead" of behind.
if (n != 0) {
return NToLastHelper(behind, current->next, n - 1);
}
// Since we now know current is n ahead of behind, if it is null
// the behind must be n from the end.
if (current->next == nullptr) {
return behind;
}
// Otherwise we need to keep going.
return NToLastHelper(behind->next, current->next, n);
}
Node *NToLast(Node *node, int n) {
// Call the helper function from the head node.
return NToLastHelper(node, node, n);
}
edit: If you want to return the value of the last node, you can just change it to:
int NToLast(Node *node, int n) {
// Call the helper function from the head node.
return NToLastHelper(node, node, n)->val;
}
This code will fail badly if node is null.
The recursion function:
int n_to_end(Node *no, int n, Node **res)
{
if(no->next == NULL)
{
if(n==0)
*res = no;
return 0;
}
else
{
int tmp = 1 + n_to_end(no->next, n, res);
if(tmp == n)
*res = no;
return tmp;
}
}
The wrapper function:
Node *n_end(Node *no, int n)
{
Node *res;
res = NULL;
int m = n_to_end(no, n, &res);
if(m < n)
{
printf("max possible n should be smaller than or equal to: %d\n", m);
}
return res;
}
The calling function:
int main()
{
List list;
list.append(3);
list.append(5);
list.append(2);
list.append(2);
list.append(1);
list.append(1);
list.append(2);
list.append(2);
Node * nth = n_end(list.head, 6);
if(nth!=NULL)
printf("value is: %d\n", nth->val);
}
This code has been tested with different inputs. Although it's a C++ version, you should be able to figure out the logic :)

Categories

Resources