Cài đặt và sử dụng Ngăn xếp – Stack trong C++ – VNTALKING

Chào mừng những bạn quay trở lại với series thuật toán – cấu trúc tài liệu và giải thuật của VNTALKING. Bài viết ngày hôm nay, tất cả chúng ta sẽ cùng nhau khám phá một loại cấu trúc tài liệu rất thông dụng, đó là ngăn xếp Stack .
Khi lập trình, tất cả chúng ta thường phải giải quyết và xử lý một lượng lớn tài liệu thô và chưa được tổ chức triển khai. Điều này đỏi hỏi cần một cấu trúc tài liệu để lưu dữ liệu và được cho phép người dùng thao tác trên tài liệu một cách hiệu suất cao .

😋 Đọc các bài viết thuật toán khác:

Giới thiệu ngăn xếp Stack

Ngăn xếp Stack là một cấu trúc dữ liệu tuyến tính hoạt động theo nguyên tắc LIFO (Last In First Out). Tức là phần tử cuối cùng được đưa vào ngăn xếp sẽ là phần tử đầu tiên được lấy ra khỏi ngăn xếp stack khi cần.

Bạn hoàn toàn có thể tưởng tượng ngăn xếp stack như một chồng sách đặt trong một cái hộp. Khi thêm một sách mới thì nó sẽ được đặt lên trên, cuốn sách ở đầu cuối được đặt ở trên đỉnh cũng sẽ là cuốn được lấy ra tiên phong .

Ví dụ minh họa ngăn xếp stack

Như bạn thấy ở hình trên, thành phần ở đầu cuối sẽ là thành phần tiên phong được lấy ra khỏi ngăn xếp stack .
Việc xóa hay thêm mới một thành phần trong stack cũng sẽ luôn thực thi ở cùng một đầu ở đầu cuối của stack .

Cách thao tác với Stack

Với ngăn xếp stack, tất cả chúng ta chỉ có những thao tác giải quyết và xử lý tài liệu sau :

  • push(): Thêm một phần tử mới vào ngăn xếp, số phần tử ngăn xếp tăng lên 1
  • pop(): Xóa một phần tử khỏi stack
  • top(): Trả về giá trị của phần tử trên đỉnh của stack. Số phần tử ngăn xếp không thay đổi.
  • isEmpty(): Kiểm tra ngăn xếp stack có rỗng hay không.
  • isFull(): Kiểm tra trạng thái stack đã đầy hay chưa.

Cài đặt ngăn xếp Stack trong C / C + +

Chúng ta sẽ cùng nhau tìm hiểu cơ chế hoạt động của hai thao tác phổ biến nhất trên stack là Push()Pop().

Lưu ý: Chúng ta thiết lập một con trỏ gọi là “top” để lưu trữ vị trí của phần tử trên cùng của stack. Điều này sẽ giúp thao tác thêm mới, xóa được thực hiện hiệu quả hơn.

Thao tác PUSH (chèn mới):

  • Đầu tiên, kiểm tra stack đã đầy hay chưa. Tức kiểm tra điều kiện tràn
  • Trong trường hợp ngăn xếp stack đã đầy, thoát thao tác với thông báo: “Stack đã đầy”.
  • Ngược lại, ngăn xếp chưa đầy, con trỏ “top” tăng lên 1, sau đó dữ liệu được thêm vào stack.

Dưới đây là code minh họa.

void stack_data::push (int a)
{
    if(top >= 5)
    {
        cout << "Overflow\n";
    }
    else
    {
        data[++top] = a;   
    }
}

Thao tác POP (xóa một phần tử):

  • Trước tiên, kiểm tra xem ngăn xếp có rỗng hay không.
  • Nếu ngăn xếp bị rỗng, thoát thao tác với thông báo: “Ngăn xếp rỗng”.
  • Ngược lại, hiển thị giá trị phần tử đang được trỏ bởi con trỏ “top”. Sau đó giảm con trỏ “top” đi 1.

Code minh họa cho thao tác Pop

int stack_data::pop ()
{
    if(top < 0)
    {
        cout << "Underflow\n";
        return 0;
    }
    else
    {
        int pop = data[top--];
        return pop;
    }
}

Cuối cùng là chương trình thiết lập stack hoàn thành xong như sau :

# include
using namespace std;
 
class stack_data
{
    public:
    int top;
    int data[5];  
    stack_data()
    {
        top = -1;
    }
 
    void push (int a);
    int pop ();
    void isEmpty();
    void isFull();
    void display();
};
 
void stack_data::push (int a)
{
    if(top >= 5)
    {
        cout << "Overflow\n";
    }
    else
    {
        data[++top] = a;   
    }
}
 
int stack_data::pop ()
{
    if(top < 0)
    {
        cout << "Underflow\n";
        return 0;
    }
    else
    {
        int pop = data[top--];
        return pop;
    }
}
 
void stack_data::isEmpty()
{
    if(top < 0)
    {
        cout << "Stack Underflow\n";
    }
    else
    {
        cout << "Stack can occupy elements.\n";
    }
}
 
void stack_data::isFull()
{
    if(top >= 5)
    {
        cout << "Overflow\n";
    }
    else
    {
        cout << "Stack is not full.\n";
    }
}
 
void stack_data::display()
{
    for(int i=0;i<5;i++)
    {
        cout<
Kết quả khi chạy chương trình trên sẽ như dưới đây :
Stack is not full.
Stack after insertion of elements:
40
99
66
40
11
Element popped from the stack:
11

Ứng dụng của Stack

Tùy vào mỗi nhu yếu đơn cử mà bạn sẽ sử dụng stack để xử lý. Dưới đây là 1 số ít ứng dụng thông dụng của ngăn xếp stack .

  • Stack hay được dùng để hoán đổi vị trí của các phần tử trong Array hoặc String.
  • Một Stack có thể cần thiết trong tình huống cần Backtracking trong một số thuật toán.
  • Trong các ứng dụng kiểu như Text editor, các tính năng undo, redo có thể sẽ cần tới stack.
  • Chuyển đổi Infix/Prefix/Postfix trong Binary Trees.

Độ phức tạp của những thao tác trong Stack

Độ phức tạp của push()pop() là như nhau, đều là: O(1)

Lý do là việc thêm mới và xóa thành phần trong stack đều thực thi ở một đầu – đỉnh của stack .

Lời kết

Như vậy, trong bài viết này, tất cả chúng ta đã hiểu được ngăn xếp stack là gì, phương pháp hoạt động giải trí cũng như ứng dụng của nó trong lập trình .

Mình hi vọng, những kiến thức này sẽ giúp ích cho bạn trong các dự án sắp tới.

Hẹn gặp lại ở bài viết sau nhé .

💦 Đọc thêm bài viết hay khác: