Where does the top variable point when a stack is implemented with an array?

Array implementation of Stack

In array implementation, the stack is formed by using the array. All the operations regarding the stack are performed using arrays. Lets see how each operation can be implemented on the stack using array data structure.

Adding an element onto the stack (push operation)

Adding an element into the top of the stack is referred to as push operation. Push operation involves following two steps.

  1. Increment the variable Top so that it can now refere to the next memory location.
  2. Add element at the position of incremented top. This is referred to as adding new element at the top of the stack.

Stack is overflown when we try to insert an element into a completely filled stack therefore, our main function must always avoid stack overflow condition.

Algorithm:

Time Complexity : o(1)

implementation of push algorithm in C language

Deletion of an element from a stack (Pop operation)

Deletion of an element from the top of the stack is called pop operation. The value of the variable top will be incremented by 1 whenever an item is deleted from the stack. The top most element of the stack is stored in an another variable and then the top is decremented by 1. the operation returns the deleted value that was stored in another variable as the result.

The underflow condition occurs when we try to delete an element from an already empty stack.

Algorithm :

Time Complexity : o(1)

Implementation of POP algorithm using C language

Visiting each element of the stack (Peek operation)

Peek operation involves returning the element which is present at the top of the stack without deleting it. Underflow condition can occur if we try to return the top element in an already empty stack.

Algorithm :

PEEK (STACK, TOP)

Time complexity: o(n)

Implementation of Peek algorithm in C language

C program

Java Program

C# Program


Next TopicDS Linked List Implementation of Stack


← prev next →


Growable array based stack

We all know about Stacks also known as Last-In-First-Out(LIFO) structures. Stack primarily has two main operation namely push and pop, where push inserts an element at top and pop removes an element from top of the stack.
Now, whenever an implementation of stack is considered its size is pre-determined or fixed. Even though it is dynamically allocated, still once it is made its size cannot be changed. And hence a condition called “stack full” arises.

Where does the top variable point when a stack is implemented with an array?

But what if a stack can grow as more elements are inserted or more elements are going to be inserted in future. Remember, we are talking about array based Stack. Growable Stack is the concept of allocating more memory such that “stack full” condition does not arises easily.
A Growable array-based Stack can be implemented by allocating new memory larger than previous stack memory and copying elements from old stack to new stack. And then at last change the name of new stack to the name which was given to old stack
There are two strategy for growable stack:
1. Tight Strategy : Add a constant amount to the old stack (N+c)
2. Growth Strategy : Double the size of old stack (2N)

Where does the top variable point when a stack is implemented with an array?

There are two operation on growable stack:
1. Regular Push Operation: Add one element at top of stack
2. Special Push Operation: Create a new stack of size greater than old stack (according to one of the strategy above) and copy all elements from old stack and then push the new element to the new stack.



Recommended: Please try your approach on {IDE} first, before moving on to the solution.




// CPP Program to implement growable array based stack
// using tight strategy
#include
using namespace std;
// constant amount at which stack is increased
#define BOUND 4
// top of the stack
int top = -1;
// length of stack
int length = 0;
// function to create new stack
int* create_new(int* a)
{
// allocate memory for new stack
int* new_a = new int[length + BOUND];
// copying the content of old stack
for (int i = 0; i < length; i++)
new_a[i] = a[i];
// re-sizing the length
length += BOUND;
return new_a;
}
// function to push new element
int* push(int* a, int element)
{
// if stack is full, create new one
if (top == length - 1)
a = create_new(a);
// insert element at top of the stack
a[++top] = element;
return a;
}
// function to pop an element
void pop(int* a)
{
top--;
}
// function to display
void display(int* a)
{
// if top is -1, that means stack is empty
if (top == -1)
cout << "Stack is Empty" << endl;
else {
cout << "Stack: ";
for (int i = 0; i <= top; i++)
cout << a[i] << " ";
cout << endl;
}
}
// Driver Code
int main()
{
// creating initial stack
int *a = create_new(a);
// pushing element to top of stack
a = push(a, 1);
a = push(a, 2);
a = push(a, 3);
a = push(a, 4);
display(a);
// pushing more element when stack is full
a = push(a, 5);
a = push(a, 6);
display(a);
a = push(a, 7);
a = push(a, 8);
display(a);
// pushing more element so that stack can grow
a = push(a, 9);
display(a);
return 0;
}




// Java Program to implement growable array based stack
// using tight strategy
class GFG
{
// constant amount at which stack is increased
static final int BOUND = 4;
// top of the stack
static int top = -1;
// length of stack
static int length = 0;
// function to create new stack
static int[] create_new(int[] a)
{
// allocate memory for new stack
int[] new_a = new int[length + BOUND];
// copying the content of old stack
for (int i = 0; i < length; i++)
new_a[i] = a[i];
// re-sizing the length
length += BOUND;
return new_a;
}
// function to push new element
static int[] push(int[] a, int element)
{
// if stack is full, create new one
if (top == length - 1)
a = create_new(a);
// insert element at top of the stack
a[++top] = element;
return a;
}
// function to pop an element
static void pop(int[] a)
{
top--;
}
// function to display
static void display(int[] a)
{
// if top is -1, that means stack is empty
if (top == -1)
System.out.println("Stack is Empty");
else
{
System.out.print("Stack: ");
for (int i = 0; i <= top; i++)
System.out.print(a[i] + " ");
System.out.println();
}
}
// Driver Code
public static void main(String args[])
{
// creating initial stack
int []a = create_new(new int[length + BOUND]);
// pushing element to top of stack
a = push(a, 1);
a = push(a, 2);
a = push(a, 3);
a = push(a, 4);
display(a);
// pushing more element when stack is full
a = push(a, 5);
a = push(a, 6);
display(a);
a = push(a, 7);
a = push(a, 8);
display(a);
// pushing more element so that stack can grow
a = push(a, 9);
display(a);
}
}
// This code is contributed by Princi Singh




# Python3 Program to implement growable array based stack
# using tight strategy
# constant amount at which stack is increased
BOUND = 4
# top of the stack
top = -1;
a = []
# length of stack
length = 0;
# function to create new stack
def create_new():
global length;
# allocate memory for new stack
new_a = [0 for i in range(length + BOUND)];
# copying the content of old stack
for i in range(length):
new_a[i] = a[i];
# re-sizing the length
length += BOUND;
return new_a
# function to push new element
def push( element):
global top, a
# if stack is full, create new one
if (top == length - 1):
a = create_new();
top +=1
# insert element at top of the stack
a[top] = element;
return a;
# function to pop an element
def pop():
global top
top -= 1;
# function to display
def display():
global top
# if top is -1, that means stack is empty
if (top == -1):
print("Stack is Empty")
else:
print("Stack: ", end = '')
for i in range(top + 1):
print(a[i], end = ' ')
print()
# Driver Code
if __name__=='__main__':
# creating initial stack
a = create_new();
# pushing element to top of stack
push(1);
push(2);
push(3);
push(4);
display();
# pushing more element when stack is full
push(5);
push(6);
display();
push(7);
push(8);
display();
# pushing more element so that stack can grow
push( 9);
display();
# This code is contributed by rutvik_56.




// C# Program to implement growable array based stack
// using tight strategy
using System;
class GFG
{
// constant amount at which stack is increased
static int BOUND = 4;
// top of the stack
static int top = -1;
// length of stack
static int length = 0;
// function to create new stack
static int[] create_new(int[] a)
{
// allocate memory for new stack
int[] new_a = new int[length + BOUND];
// copying the content of old stack
for (int i = 0; i < length; i++)
new_a[i] = a[i];
// re-sizing the length
length += BOUND;
return new_a;
}
// function to push new element
static int[] push(int[] a, int element)
{
// if stack is full, create new one
if (top == length - 1)
a = create_new(a);
// insert element at top of the stack
a[++top] = element;
return a;
}
// function to pop an element
static void pop(int[] a)
{
top--;
}
// function to display
static void display(int[] a)
{
// if top is -1, that means stack is empty
if (top == -1)
Console.WriteLine("Stack is Empty");
else
{
Console.Write("Stack: ");
for (int i = 0; i <= top; i++)
Console.Write(a[i] + " ");
Console.WriteLine();
}
}
// Driver Code
public static void Main(String []args)
{
// creating initial stack
int []a = create_new(new int[length + BOUND]);
// pushing element to top of stack
a = push(a, 1);
a = push(a, 2);
a = push(a, 3);
a = push(a, 4);
display(a);
// pushing more element when stack is full
a = push(a, 5);
a = push(a, 6);
display(a);
a = push(a, 7);
a = push(a, 8);
display(a);
// pushing more element so that stack can grow
a = push(a, 9);
display(a);
}
}
// This code is contributed by 29AjayKumar




.

Output:

Stack: 1 2 3 4 Stack: 1 2 3 4 5 6 Stack: 1 2 3 4 5 6 7 8 Stack: 1 2 3 4 5 6 7 8 9

Where does the top variable point when a stack is implemented with an array?




Article Tags :
Arrays
Stack
Practice Tags :
Arrays
Stack

Introduction

Have you always wanted to learn about stacks? Do you also want to know how to implement it in code or a way to visualize it? Then, you are at the right place. This article aims to provide you with in-depth knowledge about stack implementation in one of the easiest and systematic ways.

Before discussing more implementation, let’s brush up on our knowledge about stacks.

So, What are stacks? No, I don’t want you to think of it as a coding question; just imagine how a stack looks in the practical world.

Where does the top variable point when a stack is implemented with an array?

See this image:

Where does the top variable point when a stack is implemented with an array?
DIsks stacked

So, we have five disks stacked together, as shown above. The numbers represent the order in which we place them one by one on top of each other. So, this is what a stack looks like.

Stack is a linear data structure that allows the most recently added elements to be removed first and this feature is more popularly known as LIFO ( last in, first out). So, both the insertion and deletion of elements happen only from one end, i.e. from the top of the stack.

The main functions of the stack include –

  1. Pop – to remove the top element from the stack
  2. Push – to insert an element into the stack
  3. Peek or top – to find the top element of the stack
  4. isEmpty – to check if the stack is empty or not

Now that you are confident about the foundation, let’s think about how to mimic this stack in our code, i.e. how to implement it. Maybe you should wonder –

  • What data structures should be used?
  • How to implement the primary functions of the stack?

Non-essential operationsEdit

In many implementations, a stack has more operations than the essential "push" and "pop" operations. An example of a non-essential operation is "top of stack", or "peek", which observes the top element without removing it from the stack.[17] This could be done with a "pop" followed by a "push" to return the same data to the stack, so it is not considered an essential operation. If the stack is empty, an underflow condition will occur upon execution of either the "stack top" or "pop" operations. Additionally, many implementations provide a check if the stack is empty and one that returns its size.

Software stacksEdit

ImplementationEdit

A stack can be easily implemented either through an array or a linked list. What identifies the data structure as a stack, in either case, is not the implementation but the interface: the user is only allowed to pop or push items onto the array or linked list, with few other helper operations. The following will demonstrate both implementations, using pseudocode.

ArrayEdit

An array can be used to implement a (bounded) stack, as follows. The first element, usually at the zero offset, is the bottom, resulting in array[0] being the first element pushed onto the stack and the last element popped off. The program must keep track of the size (length) of the stack, using a variable top that records the number of items pushed so far, therefore pointing to the place in the array where the next element is to be inserted (assuming a zero-based index convention). Thus, the stack itself can be effectively implemented as a three-element structure:

structure stack: maxsize: integer top: integer items: array of item procedure initialize(stk: stack, size: integer): stk.items ← new array of size items, initially empty stk.maxsize ← size stk.top ← 0

The push operation adds an element and increments the top index, after checking for overflow:

procedure push(stk: stack, x: item): if stk.top = stk.maxsize: report overflow error else: stk.items[stk.top] ← x stk.top ← stk.top + 1

Similarly, pop decrements the top index after checking for underflow, and returns the item that was previously the top one:

procedure pop(stk: stack): if stk.top = 0: report underflow error else: stk.top ← stk.top − 1 r ← stk.items[stk.top] return r

Using a dynamic array, it is possible to implement a stack that can grow or shrink as much as needed. The size of the stack is simply the size of the dynamic array, which is a very efficient implementation of a stack since adding items to or removing items from the end of a dynamic array requires amortized O(1) time.

Linked listEdit

Another option for implementing stacks is to use a singly linked list. A stack is then a pointer to the "head" of the list, with perhaps a counter to keep track of the size of the list:

structure frame: data: item next: frame or nil structure stack: head: frame or nil size: integer procedure initialize(stk: stack): stk.head ← nil stk.size ← 0

Pushing and popping items happens at the head of the list; overflow is not possible in this implementation (unless memory is exhausted):

procedure push(stk: stack, x: item): newhead ← new frame newhead.data ← x newhead.next ← stk.head stk.head ← newhead stk.size ← stk.size + 1 procedure pop(stk: stack): if stk.head = nil: report underflow error r ← stk.head.data stk.head ← stk.head.next stk.size ← stk.size - 1 return r

Stacks and programming languagesEdit

Some languages, such as Perl, LISP, JavaScript and Python, make the stack operations push and pop available on their standard list/array types. Some languages, notably those in the Forth family (including PostScript), are designed around language-defined stacks that are directly visible to and manipulated by the programmer.

The following is an example of manipulating a stack in Common Lisp (">" is the Lisp interpreter's prompt; lines not starting with ">" are the interpreter's responses to expressions):

> (setf stack (list 'a 'b 'c)) ;; set the variable "stack" (A B C) > (pop stack) ;; get top (leftmost) element, should modify the stack A > stack ;; check the value of stack (B C) > (push 'new stack) ;; push a new top onto the stack (NEW B C)

Several of the C++ Standard Library container types have push_back and pop_back operations with LIFO semantics; additionally, the stack template class adapts existing containers to provide a restricted API with only push/pop operations. PHP has an SplStack class. Java's library contains a Stack class that is a specialization of Vector. Following is an example program in Java language, using that class.

import java.util.Stack; class StackDemo { public static void main(String[]args) { Stack stack = new Stack(); stack.push("A"); // Insert "A" in the stack stack.push("B"); // Insert "B" in the stack stack.push("C"); // Insert "C" in the stack stack.push("D"); // Insert "D" in the stack System.out.println(stack.peek()); // Prints the top of the stack ("D") stack.pop(); // removing the top ("D") stack.pop(); // removing the next top ("C") } }