Friday, February 7, 2014

Implementing 2 stacks in an array

Problem
 How can you implement two stacks in a single array, where no stack overflows until no space left in the entire array space?


Lets denote the stacks by suffix 1 and 2. Now we have to implement the following methods :
push1(int x) –> pushes x to first stack
push2(int x) –> pushes x to second stack
pop1() –> pops an element from first stack and return the popped element
pop2() –> pops an element from second stack and return the popped element

Solution
Method 1 (Divide the space in two halves)
A simple way to implement two stacks is two divide the array in two halves and assign the half half space to two stacks, i.e., use arr[0] to arr[n/2] for stack1, and arr[n/2+1] to arr[n-1] for stack2 where arr[] is the array to be used to implement two stacks and size of array be n.
The problem with this method is inefficient use of array space. A stack push operation may result in stack overflow even if there is space available in arr[]. For example, say the array size is 6 and we push 3 elements to stack1 and do not push anything to second stack2. When we push 4th element to stack1, there will be overflow even if we have space for 3 more elements in array.

Method 2 (A space efficient implementation)
This method efficiently utilizes the available space. It doesn’t cause an overflow if there is space available in arr[]. The idea is to start two stacks from two extreme corners of arr[]. stack1 starts from the leftmost element, the first element in stack1 is pushed at index 0. The stack2 starts from the rightmost corner, the first element in stack2 is pushed at index (n-1). Both stacks grow (or shrink) in opposite direction.

Here is the code in java:
package com.vaani.ds.stack.impl;

public class TwoStacks {

 int[] arr;
 int size;
 int top1, top2;

 public TwoStacks(int n) // constructor
 {
  size = n;
  arr = new int[n];
  top1 = -1;
  top2 = size;
 }

 // Method to push an element x to stack1
 void push1(int x) {
  // There is at least one empty space for new element
  if (top1 < top2 - 1) {
   top1++;
   arr[top1] = x;
  } else {
   throw new IllegalStateException("Stack Overflow");
  }
 }

 // Method to push an element x to stack2
 void push2(int x) {
  // There is at least one empty space for new element
  if (top1 < top2 - 1) {
   top2--;
   arr[top2] = x;
  } else {
   throw new IllegalStateException("Stack Overflow");
  }
 }

 // Method to pop an element from first stack
 int pop1() {
  if (top1 >= 0) {
   int x = arr[top1];
   top1--;
   return x;
  } else {
   throw new IllegalStateException("Stack UnderFlow");
  }
 }

 // Method to pop an element from second stack
 int pop2() {
  if (top2 < size) {
   int x = arr[top2];
   top2++;
   return x;
  } else {
   throw new IllegalStateException("Stack UnderFlow");
  }
 }

 /* Driver program to test twStacks class */
 public static void main(String[] args) {
  TwoStacks ts = new TwoStacks(5);
  ts.push1(5);
  ts.push2(10);
  ts.push2(15);
  ts.push1(11);
  ts.push2(7);
  System.out.println("Popped element from stack1 is " + ts.pop1());
  ts.push2(40);
  System.out.println("\nPopped element from stack2 is " + ts.pop2());

 }
}


Output:
  Popped element from stack1 is 11
  Popped element from stack2 is 40

Time complexity of all 4 operations of TwoStacks is O(1).

3 stacks in an array is extended in a separate post.

Thanks.
.

0 comments:

Post a Comment