Cấu trúc dữ liệu và thuật toán - Ngăn xếp
Ngăn xếp là một kiểu dữ liệu trừu tượng (ADT), thường được sử dụng trong hầu hết các ngôn ngữ lập trình. Nó được đặt tên là ngăn xếp vì nó hoạt động giống như một ngăn xếp trong thế giới thực, chẳng hạn - một bộ bài hoặc một đống đĩa, v.v.
Một ngăn xếp trong thế giới thực chỉ cho phép các hoạt động ở một đầu. Ví dụ, chúng ta chỉ có thể đặt hoặc lấy thẻ hoặc đĩa ở trên cùng của ngăn xếp. Tương tự như vậy, Stack ADT chỉ cho phép tất cả các hoạt động dữ liệu ở một đầu. Tại bất kỳ thời điểm nào, chúng ta chỉ có thể truy cập phần tử trên cùng của ngăn xếp.
Tính năng này làm cho nó trở thành cấu trúc dữ liệu LIFO. LIFO là viết tắt của Last-in-first-out. Ở đây, phần tử được đặt (chèn hoặc thêm) cuối cùng, được truy cập đầu tiên. Trong thuật ngữ ngăn xếp, hoạt động chèn được gọi làPUSH hoạt động và hoạt động loại bỏ được gọi là POP hoạt động.
Biểu diễn ngăn xếp
Sơ đồ sau mô tả một ngăn xếp và các hoạt động của nó:
Một ngăn xếp có thể được thực hiện bằng Mảng, Cấu trúc, Con trỏ và Danh sách Liên kết. Ngăn xếp có thể có kích thước cố định hoặc có thể có cảm giác thay đổi kích thước động. Ở đây, chúng ta sẽ triển khai ngăn xếp bằng cách sử dụng các mảng, làm cho nó trở thành một triển khai ngăn xếp có kích thước cố định.
Hoạt động cơ bản
Các hoạt động ngăn xếp có thể liên quan đến việc khởi tạo ngăn xếp, sử dụng nó và sau đó khử khởi tạo nó. Ngoài những nội dung cơ bản này, ngăn xếp được sử dụng cho hai hoạt động chính sau:
push() - Đẩy (lưu trữ) một phần tử trên ngăn xếp.
pop() - Loại bỏ (truy cập) một phần tử khỏi ngăn xếp.
Khi dữ liệu được PUSHed vào ngăn xếp.
Để sử dụng ngăn xếp một cách hiệu quả, chúng ta cũng cần kiểm tra trạng thái của ngăn xếp. Với cùng mục đích, chức năng sau được thêm vào ngăn xếp:
peek() - lấy phần tử dữ liệu trên cùng của ngăn xếp mà không cần xóa nó.
isFull() - kiểm tra xem ngăn xếp đã đầy chưa.
isEmpty() - kiểm tra xem ngăn xếp có trống không.
Tại mọi thời điểm, chúng tôi duy trì một con trỏ đến dữ liệu PUSHed cuối cùng trên ngăn xếp. Vì con trỏ này luôn đại diện cho phần trên cùng của ngăn xếp, do đó có têntop. Cáctop con trỏ cung cấp giá trị cao nhất của ngăn xếp mà không thực sự loại bỏ nó.
Trước tiên, chúng ta nên tìm hiểu về các thủ tục để hỗ trợ các hàm ngăn xếp -
nhìn trộm ()
Thuật toán của hàm peek () -
begin procedure peek
return stack[top]
end procedure
Thực hiện hàm peek () trong ngôn ngữ lập trình C -
Example
int peek() {
return stack[top];
}
isfull ()
Thuật toán của hàm isfull () -
begin procedure isfull
if top equals to MAXSIZE
return true
else
return false
endif
end procedure
Thực hiện hàm isfull () trong ngôn ngữ lập trình C.
Example
bool isfull() {
if(top == MAXSIZE)
return true;
else
return false;
}
isempty ()
Thuật toán của hàm isempty () -
begin procedure isempty
if top less than 1
return true
else
return false
endif
end procedure
Việc triển khai hàm isempty () trong ngôn ngữ lập trình C hơi khác. Chúng tôi khởi tạo đỉnh ở -1, vì chỉ số trong mảng bắt đầu từ 0. Vì vậy, chúng tôi kiểm tra xem đỉnh dưới 0 hay -1 để xác định xem ngăn xếp có trống hay không. Đây là mã -
Example
bool isempty() {
if(top == -1)
return true;
else
return false;
}
Hoạt động đẩy
Quá trình đưa một phần tử dữ liệu mới vào ngăn xếp được gọi là Hoạt động Đẩy. Hoạt động đẩy bao gồm một loạt các bước -
Step 1 - Kiểm tra xem chồng có đầy không.
Step 2 - Nếu ngăn xếp đầy, tạo ra lỗi và thoát.
Step 3 - Nếu ngăn xếp không đầy, tăng dần top để chỉ không gian trống tiếp theo.
Step 4 - Thêm phần tử dữ liệu vào vị trí ngăn xếp, nơi đỉnh đang trỏ.
Step 5 - Trả lại thành công.
Nếu danh sách liên kết được sử dụng để triển khai ngăn xếp, thì ở bước 3, chúng ta cần cấp phát không gian động.
Thuật toán cho hoạt động PUSH
Một thuật toán đơn giản cho hoạt động Đẩy có thể được suy ra như sau:
begin procedure push: stack, data
if stack is full
return null
endif
top ← top + 1
stack[top] ← data
end procedure
Việc thực hiện thuật toán này trong C, rất dễ dàng. Xem đoạn mã sau -
Example
void push(int data) {
if(!isFull()) {
top = top + 1;
stack[top] = data;
} else {
printf("Could not insert data, Stack is full.\n");
}
}
Hoạt động Pop
Truy cập nội dung trong khi xóa nội dung đó khỏi ngăn xếp, được gọi là Thao tác bật. Trong triển khai mảng của thao tác pop (), phần tử dữ liệu không thực sự bị xóa, thay vào đótopđược giảm xuống vị trí thấp hơn trong ngăn xếp để trỏ đến giá trị tiếp theo. Nhưng trong triển khai danh sách liên kết, pop () thực sự loại bỏ phần tử dữ liệu và phân bổ không gian bộ nhớ.
Hoạt động Pop có thể bao gồm các bước sau:
Step 1 - Kiểm tra xem ngăn xếp có trống không.
Step 2 - Nếu ngăn xếp trống, tạo ra lỗi và thoát.
Step 3 - Nếu ngăn xếp không trống, hãy truy cập vào phần tử dữ liệu tại đó top đang trỏ.
Step 4 - Giảm giá trị của top 1.
Step 5 - Trả lại thành công.
Thuật toán cho hoạt động pop
Một thuật toán đơn giản cho hoạt động Pop có thể được suy ra như sau:
begin procedure pop: stack
if stack is empty
return null
endif
data ← stack[top]
top ← top - 1
return data
end procedure
Việc triển khai thuật toán này trong C, như sau:
Example
int pop(int data) {
if(!isempty()) {
data = stack[top];
top = top - 1;
return data;
} else {
printf("Could not retrieve data, Stack is empty.\n");
}
}
Để có một chương trình ngăn xếp hoàn chỉnh bằng ngôn ngữ lập trình C, vui lòng nhấp vào đây .