Software Development Exam  >  Software Development Notes  >  DSA in C++  >  Abstraction in C++

Abstraction in C++ | DSA in C++ - Software Development PDF Download

Introduction

Abstraction is an essential concept in computer programming and plays a significant role in designing efficient and maintainable software. In the context of Data Structures and Algorithms (DSA) in C++, abstraction allows us to hide complex implementation details and provide a simplified interface to the users.

In this article, we will explore the concept of abstraction in DSA using the C++ programming language. We will discuss why abstraction is important, how it can be achieved, and provide multiple examples and code snippets to illustrate different aspects of abstraction.

Why Abstraction?

Abstraction allows us to focus on the high-level functionality of a program without worrying about the low-level implementation details. By hiding the complexity, abstraction provides several benefits:

  • Simplicity: Abstraction simplifies the understanding and usage of complex data structures and algorithms by providing a clean and intuitive interface.
  • Modularity: Abstraction promotes modularity in software design, allowing different parts of a program to be developed independently and easily maintained.
  • Security: By hiding implementation details, abstraction prevents unauthorized access or modification of sensitive data.
  • Code Reusability: Abstraction facilitates code reuse as it provides a well-defined interface that can be used by multiple programs or components.

Achieving Abstraction in DSA

Abstraction in DSA can be achieved through the use of classes in C++. A class is a user-defined data type that encapsulates data and functions into a single unit. We can use classes to define abstract data types that hide the implementation details and provide a clear interface for working with data structures and algorithms.
Let's look at some examples to understand how abstraction works in DSA using C++.

Example 1: Abstract Data Type - Stack

A stack is a commonly used abstract data type that follows the "Last In, First Out" (LIFO) principle. To create an abstraction for a stack, we can define a Stack class with appropriate member functions and data members.

class Stack {

private:

    int data[100];

    int top;


public:

    Stack() {

        top = -1;

    }


    void push(int value) {

        if (top >= 99) {

            cout << "Stack Overflow!" << endl;

            return;

        }

        data[++top] = value;

    }


    int pop() {

        if (top < 0) {

            cout << "Stack Underflow!" << endl;

            return -1;

        }

        return data[top--];

    }

};

In the above code, we have defined a 'Stack' class with private 'data' members data and 'top', representing the array of elements and the index of the top element, respectively. The class also provides public member functions 'push()' and 'pop()' to add and remove elements from the stack.
Now, let's see how we can use this 'Stack' class:

int main() {

    Stack myStack;

    myStack.push(5);

    myStack.push(10);

    myStack.push(15);


    cout << myStack.pop() << endl;

    cout << myStack.pop() << endl;

    cout << myStack.pop() << endl;


    return 0;

}

Output:

15

10

5

In the above code, we create an instance of the 'Stack' class called 'myStack' and perform operations on it using the 'push()' and 'pop()' member functions. The output demonstrates the LIFO behavior of the stack.

Example 2: Abstract Data Type - Queue

Another commonly used abstract data type is a queue, which follows the "First In, First Out" (FIFO) principle. Let's define a 'Queue' class to abstract the queue data structure:

class Queue {

private:

    int data[100];

    int front;

    int rear;


public:

    Queue() {

        front = -1;

        rear = -1;

    }


    void enqueue(int value) {

        if (rear >= 99) {

            cout << "Queue Overflow!" << endl;

            return;

        }

        if (front == -1)

            front = 0;

        data[++rear] = value;

    }


    int dequeue() {

        if (front == -1 || front > rear) {

            cout << "Queue Underflow!" << endl;

            return -1;

        }

        return data[front++];

    }

};

In this example, we have defined a 'Queue' class with private data members 'data', 'front', and 'rear'. The class provides public member functions 'enqueue()' and 'dequeue()' to add and remove elements from the queue.
Here's how we can use the 'Queue' class:

int main() {

    Queue myQueue;

    myQueue.enqueue(5);

    myQueue.enqueue(10);

    myQueue.enqueue(15);


    cout << myQueue.dequeue() << endl;

    cout << myQueue.dequeue() << endl;

    cout << myQueue.dequeue() << endl;


    return 0;

}

Output:

5

10

15

In the above code, we create an instance of the 'Queue' class called 'myQueue' and perform operations on it using the 'enqueue()' and 'dequeue()' member functions. The output demonstrates the FIFO behavior of the queue.

Sample Problems

Now that we have a basic understanding of abstraction in DSA using C++, let's explore a couple of sample problems to apply our knowledge:

Problem 1: Implement a Stack using an Array
Write a C++ program to implement a stack using an array. The program should provide the following operations:
push(element): Add an element to the top of the stack.

  • 'pop()': Remove and return the top element from the stack.
  • 'isEmpty()': Check if the stack is empty.
  • 'isFull()': Check if the stack is full.

#include <iostream>

using namespace std;


class Stack {

private:

    int data[100];

    int top;


public:

    Stack() {

        top = -1;

    }


    void push(int value) {

        if (top >= 99) {

            cout << "Stack Overflow!" << endl;

            return;

        }

        data[++top] = value;

    }


    int pop() {

        if (top < 0) {

            cout << "Stack Underflow!" << endl;

            return -1;

        }

        return data[top--];

    }


    bool isEmpty() {

        return (top == -1);

    }


    bool isFull() {

        return (top == 99);

    }

};


int main() {

    Stack myStack;

    cout << myStack.isEmpty() << endl;


    myStack.push(5);

    myStack.push(10);

    myStack.push(15);


    cout << myStack.pop() << endl;

    cout << myStack.pop() << endl;

    cout << myStack.pop() << endl;


    cout << myStack.isEmpty() << endl;

    cout << myStack.isFull() << endl;


    return 0;

}

Output:

1

15

10

5

1

0

Problem 2: Implement a Queue using a Linked List
Write a C++ program to implement a queue using a linked list. The program should provide the following operations:

  • 'enqueue(element)': Add an element to the rear of the queue.
  • 'dequeue()': Remove and return the front element from the queue.
  • 'isEmpty()': Check if the queue is empty.
  • 'isFull()': Check if the queue is full.

#include <iostream>

using namespace std;


class Node {

public:

    int data;

    Node* next;


    Node(int value) {

        data = value;

        next = nullptr;

    }

};


class Queue {

private:

    Node* front;

    Node* rear;


public:

    Queue() {

        front = nullptr;

        rear = nullptr;

    }


    void enqueue(int value) {

        Node* newNode = new Node(value);

        if (rear == nullptr) {

            front = newNode;

            rear = newNode;

        } else {

            rear->next = newNode;

            rear = newNode;

        }

    }


    int dequeue() {

        if (front == nullptr) {

            cout << "Queue Underflow!" << endl;

            return -1;

        }

        int value = front->data;

        Node* temp = front;

        front = front->next;

        delete temp;

        if (front == nullptr)

            rear = nullptr;

        return value;

    }


    bool isEmpty() {

        return (front == nullptr);

    }


    bool isFull() {

        return false; // Linked list implementation does not have a fixed size

    }

};


int main() {

    Queue myQueue;

    cout << myQueue.isEmpty() << endl;


    myQueue.enqueue(5);

    myQueue.enqueue(10);

    myQueue.enqueue(15);


    cout << myQueue.dequeue() << endl;

    cout << myQueue.dequeue() << endl;

    cout << myQueue.dequeue() << endl;


    cout << myQueue.isEmpty() << endl;

    cout << myQueue.isFull() << endl;


    return 0;

}

Output:

1

5

10

15

1

0

Conclusion

Abstraction is a powerful concept in DSA and programming in general. It allows us to create abstract data types that hide implementation details and provide a simplified interface. Through the use of classes and appropriate member functions, we can achieve abstraction in C++.
By abstracting data structures and algorithms, we can write cleaner, modular, and reusable code. It simplifies the usage of complex functionality, enhances code security, and promotes code maintenance.

The document Abstraction in C++ | DSA in C++ - Software Development is a part of the Software Development Course DSA in C++.
All you need of Software Development at this link: Software Development
153 videos|115 docs|24 tests

Top Courses for Software Development

153 videos|115 docs|24 tests
Download as PDF
Explore Courses for Software Development exam

Top Courses for Software Development

Signup for Free!
Signup to see your scores go up within 7 days! Learn & Practice with 1000+ FREE Notes, Videos & Tests.
10M+ students study on EduRev
Related Searches

Extra Questions

,

Abstraction in C++ | DSA in C++ - Software Development

,

Abstraction in C++ | DSA in C++ - Software Development

,

Sample Paper

,

study material

,

practice quizzes

,

Abstraction in C++ | DSA in C++ - Software Development

,

past year papers

,

mock tests for examination

,

Viva Questions

,

Semester Notes

,

pdf

,

Exam

,

shortcuts and tricks

,

Objective type Questions

,

ppt

,

Important questions

,

Free

,

Summary

,

Previous Year Questions with Solutions

,

MCQs

,

video lectures

;