Explore all courses in this category.
Explore all courses in this category.
Nguyễn Đình Cường
0 comment
09 Nov, 2026
Cách đơn giản nhất để hiểu stack và queue là nhìn vào đời sống: chồng đĩa trong bếp và hàng người chờ mua trà sữa. Hai cấu trúc này khác nhau ở một điểm rất nhỏ nhưng quyết định cách chúng được dùng.
Stack (ngăn xếp) hoạt động theo nguyên tắc LIFO - Last In, First Out. Bạn đặt đĩa mới lên đỉnh chồng và khi lấy, bạn cũng lấy đĩa trên cùng. Hai thao tác chính:
Trong Python, bạn có thể dùng list như một stack:
stack = []
stack.append("A") # push
stack.append("B")
stack.append("C")
print(stack.pop()) # C
print(stack.pop()) # B
print(stack) # ['A']Bài kiểm tra ngoặc là ví dụ kinh điển:
def ngoac_hop_le(s):
cap = {")": "(", "]": "[", "}": "{"}
stack = []
for c in s:
if c in "([{":
stack.append(c)
elif c in cap:
if not stack or stack.pop() != cap[c]:
return False
return not stack
print(ngoac_hop_le("{[()]}")) # True
print(ngoac_hop_le("([)]")) # FalseQueue (hàng đợi) theo nguyên tắc FIFO - First In, First Out. Ai đến trước được phục vụ trước. Thao tác chính là enqueue (thêm vào cuối) và dequeue (lấy ra ở đầu).
Với Python, nên dùng collections.deque thay vì list, vì lấy phần tử đầu của list phải dời cả danh sách nên chậm:
from collections import deque
hang = deque()
hang.append("Lan") # enqueue
hang.append("Minh")
hang.append("Hà")
print(hang.popleft()) # Lan (dequeue)
print(hang.popleft()) # Minh
print(len(hang)) # 1| Tiêu chí | Stack | Queue |
|---|---|---|
| Nguyên tắc | LIFO | FIFO |
| Thêm | Vào đỉnh (push) | Vào cuối (enqueue) |
| Lấy | Từ đỉnh (pop) | Từ đầu (dequeue) |
| Ví dụ | Chồng đĩa, Undo | Xếp hàng, hàng chờ |
Cả hai thao tác chính đều nhanh nếu cài đặt đúng, nên chúng được dùng rộng rãi khi cần xử lý dữ liệu theo thứ tự cố định.
Nút Back và Forward của trình duyệt có thể mô phỏng bằng hai stack:
class TrinhDuyet:
def __init__(self, trang_chu):
self.hien_tai = trang_chu
self.lui = []
self.tien = []
def truy_cap(self, url):
self.lui.append(self.hien_tai)
self.hien_tai = url
self.tien.clear()
def back(self):
if self.lui:
self.tien.append(self.hien_tai)
self.hien_tai = self.lui.pop()
def forward(self):
if self.tien:
self.lui.append(self.hien_tai)
self.hien_tai = self.tien.pop()
b = TrinhDuyet("trang-chu")
b.truy_cap("khoa-hoc")
b.truy_cap("bai-viet")
b.back()
print(b.hien_tai) # khoa-hoc
b.forward()
print(b.hien_tai) # bai-vietMỗi lần truy cập trang mới, danh sách "tiến" bị xóa, đúng như trình duyệt thật. Hãy thêm tính năng đếm số trang trong lịch sử như bài tập tiếp theo. Ví dụ này cho thấy hai cấu trúc đơn giản có thể mô tả một hành vi quen thuộc.
ds.pop(0) phải dời toàn bộ phần tử phía sau nên chậm với dữ liệu lớn; hãy dùng deque.IndexError. Luôn kiểm tra if stack: trước.Bài tập gợi ý: đảo ngược một chuỗi bằng stack; tính giá trị biểu thức hậu tố như 3 4 + 2 * (đẩy số vào stack, gặp phép toán thì lấy hai số ra tính rồi đẩy kết quả lại); mô phỏng hàng chờ ở quầy với mỗi khách mất một số phút phục vụ khác nhau. Bài biểu thức hậu tố đặc biệt hay vì nó cho thấy stack có thể thay thế cả việc phân tích ngoặc phức tạp.
Stack là chồng đĩa, queue là hàng người chờ, và khác biệt nằm ở đầu nào được lấy ra. Hãy thử tự cài đặt cả hai từ list, giải bài kiểm tra ngoặc và mô phỏng hàng chờ. Khi gặp bài toán cần thứ tự xử lý, bạn sẽ biết nên chọn cấu trúc nào.
Bạn có thể tiếp tục hành trình với những khóa học lập trình trên codebem.com, học theo tốc độ của riêng mình.
Nguyễn Đình Cường
0 comment