Home C++ C++ Standard Template Library (STL) stack tutorial

C++ Standard Template Library (STL) stack tutorial

The stack in the C++ Standard Template Library (STL) is a container adapter that implements a Last-In-First-Out (LIFO) structure.

Elements are added and removed from the same end of the stack (the “top”), making it ideal for tasks where the last added element needs to be processed first.

Key Features of stack

  1. LIFO Structure: Elements are added and removed from the top.
  2. Efficient Operations: push, pop, and top operations are constant time.
  3. Restricted Access: Only the top element can be accessed directly; no random access.

Basic Syntax

#include <stack>
using namespace std;

stack<Type> s;

Let’s explore the stack with examples demonstrating common operations.

1. Basic Operations: push, pop, and top

The push function adds an element to the top of the stack, pop removes the top element, and top retrieves the top element.

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Adding elements
    s.push(10);
    s.push(20);
    s.push(30);

    // Access top element
    cout << "Top element: " << s.top() << endl;

    // Remove elements and display them
    cout << "Elements in the stack: ";
    while (!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }
    cout << endl;

    return 0;
}

Output:

Top element: 30
Elements in the stack: 30 20 10 

2. Checking if the Stack is Empty

The empty function checks if the stack is empty, returning true if it is and false otherwise.

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Check if the stack is empty
    if (s.empty()) {
        cout << "The stack is empty." << endl;
    }

    // Add an element and check again
    s.push(5);
    if (!s.empty()) {
        cout << "The stack is not empty." << endl;
    }

    return 0;
}

Output:

The stack is empty.
The stack is not empty.

3. Getting the Size of the Stack

Use the size function to retrieve the number of elements in the stack.

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Insert elements
    s.push(10);
    s.push(20);
    s.push(30);

    // Display the size of the stack
    cout << "Size of the stack: " << s.size() << endl;

    return 0;
}

Output:

Size of the stack: 3

4. Using stack with Custom Data Types

You can store custom objects in a stack as long as they have a valid copy constructor and assignment operator.

#include <iostream>
#include <stack>
#include <string>
using namespace std;

// Custom structure for storing person information
struct Person {
    string name;
    int age;

    Person(string n, int a) : name(n), age(a) {}
};

int main() {
    stack<Person> s;

    // Insert custom objects
    s.push(Person("Alice", 25));
    s.push(Person("Bob", 30));
    s.push(Person("Charlie", 35));

    // Access and display elements
    cout << "People in the stack:" << endl;
    while (!s.empty()) {
        Person p = s.top();
        cout << "Name: " << p.name << ", Age: " << p.age << endl;
        s.pop();
    }

    return 0;
}

Output:

People in the stack:
Name: Charlie, Age: 35
Name: Bob, Age: 30
Name: Alice, Age: 25

5. Reversing a Sequence Using a Stack

You can use a stack to reverse a sequence of elements, as elements are retrieved in reverse order.

#include <iostream>
#include <stack>
#include <vector>
using namespace std;

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};
    stack<int> s;

    // Push elements to the stack
    for (int num : numbers) {
        s.push(num);
    }

    // Pop elements to display them in reverse order
    cout << "Reversed sequence: ";
    while (!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }
    cout << endl;

    return 0;
}

Output:

Reversed sequence: 5 4 3 2 1 

6. Using stack with Strings

You can use stack to manage strings, which is useful for applications like reversing words or checking balanced parentheses.

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main() {
    stack<string> s;

    // Insert strings
    s.push("apple");
    s.push("banana");
    s.push("cherry");

    // Display and remove strings in LIFO order
    cout << "Strings in the stack: ";
    while (!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }
    cout << endl;

    return 0;
}

Output:

Strings in the stack: cherry banana apple 

7. Using stack to Check for Balanced Parentheses

A stack is useful for checking if parentheses in an expression are balanced.

#include <iostream>
#include <stack>
#include <string>
using namespace std;

bool isBalanced(const string &str) {
    stack<char> s;
    for (char ch : str) {
        if (ch == '(') {
            s.push(ch);
        } else if (ch == ')') {
            if (s.empty()) return false;
            s.pop();
        }
    }
    return s.empty();
}

int main() {
    string expr = "(1 + (2 * (3 + 4)))";

    if (isBalanced(expr)) {
        cout << "The expression has balanced parentheses." << endl;
    } else {
        cout << "The expression does not have balanced parentheses." << endl;
    }

    return 0;
}

Output:

The expression has balanced parentheses.

8. Clearing All Elements from a Stack

To clear all elements in a stack, use a loop to remove each element with pop.

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Insert elements
    s.push(10);
    s.push(20);
    s.push(30);

    // Clear the stack
    while (!s.empty()) {
        s.pop();
    }

    // Verify that the stack is empty
    cout << "Is the stack empty? " << (s.empty() ? "Yes" : "No") << endl;

    return 0;
}

Output:

Is the stack empty? Yes

9. Using stack to Evaluate a Postfix Expression

stack is commonly used to evaluate postfix (Reverse Polish Notation) expressions.

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int evaluatePostfix(const string &expr) {
    stack<int> s;
    for (char ch : expr) {
        if (isdigit(ch)) {
            s.push(ch - '0'); // Convert char to int
        } else {
            int b = s.top(); s.pop();
            int a = s.top(); s.pop();
            switch (ch) {
                case '+': s.push(a + b); break;
                case '-': s.push(a - b); break;
                case '*': s.push(a * b); break;
                case '/': s.push(a / b); break;
            }
        }
    }
    return s.top();
}

int main() {
    string postfixExpr = "53+82-*";
    cout << "Result of postfix expression evaluation: " << evaluatePostfix(postfixExpr) << endl;

    return 0;
}

Output:

Result of postfix expression evaluation: 16

Summary Table of stack Operations

Operation Code Example Description
Initialize stack<int> s; Initializes an empty stack
Add Element s.push(10); Adds an element to the top of the stack
Remove Element s.pop(); Removes the top element
Access Top s.top(); Accesses the top element
Check if Empty s.empty(); Returns true if the stack is empty
Get Size s.size(); Returns the number of elements in the stack
Custom Data Types stack<CustomType> s; Stores custom objects
Clear All Elements Use while (!s.empty()) { s.pop(); } Clears all elements manually
Check Balanced Parentheses isBalanced(expression); Uses stack to check if parentheses are balanced
Evaluate Postfix Expression evaluatePostfix(expr); Uses stack to evaluate a postfix expression

Complete Example

This example demonstrates initializing a stack, adding and removing elements, checking if elements exist, and clearing the stack.

#include <iostream>
#include <stack>
using namespace std;

int main() {
    stack<int> s;

    // Adding elements
    s.push(5);
    s.push(10);
    s.push(15);

    // Display the top element
    cout << "Top element: " << s.top() << endl;

    // Display all elements in the stack
    cout << "Elements in the stack: ";
    while (!s.empty()) {
        cout << s.top() << " ";
        s.pop();
    }
    cout << endl;

    // Check if stack is empty after clearing
    cout << "Is the stack empty? " << (s.empty() ? "Yes" : "No") << endl;

    return 0;
}

Sample Output:

Top element: 15
Elements in the stack: 15 10 5 
Is the stack empty? Yes

Key Takeaways

  • stack in C++ provides a LIFO structure, useful for scenarios where the most recent element needs to be processed first.
  • Key operations include push, pop, top, empty, and size.
  • It is commonly used for applications like expression evaluation, parentheses matching, and reversing sequences where a LIFO structure is ideal.

You may also like