You are on page 1of 8

STUDY WITH ME CẤU TRÚC DỮ LIỆU VÀ GIẢI THUẬT

CẤU TRÚC DỮ LIỆU NGĂN XẾP VÀ HÀNG ĐỢI

I. CẤU TRÚC DỮ LIỆU NGĂN XẾP


1. Khái niệm về ngăn xếp (stack)
Stack là một cấu trúc dữ liệu tuyến tính với các hoạt động được thực hiện theo một
thứ tự cụ thể. Thứ tự có thể là LIFO (Last In First Out – vào sau lại ra trước) hoặc FILO
(First In Last Out – vào đầu tiên nhưng ra lại sau cùng). Hiểu đơn giản hơn, Stack là
ngăn xếp, bạn có thể tưởng tượng nó như một chồng sách và sách nào để lên sau cùng
sẽ được lấy ra trước…
Chủ yếu Stack có ba hàm cơ bản sau được thực hiện:
• Push: Thêm một mục(phần tử, thành phần) trong stack. Nếu stack đầy, thì nó
được cho là điều kiện Tràn.
• Pop: Loại bỏ một mục khỏi stack. Các mục được xuất hiện theo thứ tự đảo
ngược mà chúng được Push. Nếu stack trống, thì nó được cho là điều kiện trống.
• Peek hoặc Top: Trả về phần tử trên cùng của stack.
• isEmpty: Trả về true nếu stack trống, ngược lại là false.
2. Khởi tạo stack
2.1. Định nghĩa kiểu dữ liệu stack

• Vì stack là 1 dạng đặc biệt của danh sách liên kết nên ta có thể dùng kiểu dữ liệu
Node đã trình bày ở bài danh sách liên kết để biểu diễn kiểu dữ liệu của stack
• Định nghĩa 1 class Stack với kiểu dữ liệu generic T và 1 node trên cùng gọi là
top

2.2. Thêm 1 phần tử vào ngăn xếp(push)

• Kiểm tra xem ngăn xếp có nil không, nếu nil thì gán đỉnh ngăn xếp vào phần tử
muốn thêm vào.
• Nếu đỉnh ngăn xếp không nil, tạo 1 nút mới, gán phần tử muốn thêm vào nút đó,
gán đỉnh ngăn xếp vào nút vừa tạo.
2.3. Lấy 1 phần tử ra khỏi danh sách(pop)

• Kiểm tra danh sách đỉnh có rỗng không, nếu rỗng thì kết thúc.
• Nếu đỉnh danh sách không rỗng, kiểm tra nút đỉnh trỏ đến có rỗng không nếu
rỗng thì gán đỉnh danh sách bằng nil( trường hợp danh sách chỉ có 1 phần sau
khi lấy 1 phần tử ra thì danh sách trở thành rỗng), còn không gán đỉnh của danh
sách vào nút tiếp theo.
2.4. Xem phần tử đầu danh sách

• kiểm tra xem đỉnh của danh sách có rỗng không, nếu rỗng thì trả về nil còn không
trả về giá trị của đỉnh danh sách.

2.5. Test thử danh sách


2.5.1 Test build stack
2.5.2 Test push stack

2.5.3 Test pop stack

3. Một số ứng dụng của ngăn xếp

3.1 Đảo ngược xâu ký tự

• Bài toán đảo ngược xâu ký tự yêu cầu hiển thị các ký tự của 1 xâu ký tự theo
chiều ngược lại.
• Ký tự cuối cùng của xâu sẽ được hiển thị trước, tiếp theo là ký tự sát ký tự cuối
… và ký tự đầu tiên sẽ được hiển thị đầu tiên.
• Để giải quyết bài toán, ta chỉ cần duyệt từ đầu đến cuối xâu, lần lượt cho các ký
tự vào ngăn xếp.
• Khi đó, các ký tự đầu tiên sẽ vào trước, tiếp theo đến ký tự thứ 2 … ký tự cuối
cùng vào sau cùng. Sau khi đã cho toàn bộ ký tự của xâu vào ngăn xếp, lần lượt
lấy các phần tử ra khỏi ngăn xếp và hiển thị lên màn hình.
3.2 Duyệt biểu thức hậu tố
Gặp toán hạng: đẩy vào stack - Gặp toán tử 1 ngôi: lấy ra 1 toán hạng trong stack, áp
dụng toán tử lên toán hạng và đẩy kết quả trở lại stack - Gặp toán tử 2 ngôi: lấy 2 toán
hạng ở đỉnh stack theo thứ tự, áp dụng toán tử lên 2 toán hạng đó, kết quả lại đẩy vào
stack - Kết thúc, đưa ra kết quả là giá trị ở đỉnh stack - Vd định giá biểu thức hậu tố.
3.3 Chuyển biểu thức dạng trung tố sang hậu tố
Duyệt lần lượt biểu thức trung tố từ trái qua phải - Gặp toán hạng: viết sang biểu thức
kết quả - Gặp toán tử có độ ưu tiên dưới 6 + Nếu stack rỗng hoặc đỉnh stack là toán tử
có độ ưu tiên nhỏ hơn hoặc là ' (' đẩy toán tử đang xét vào stack + Ngược lại: lấy các
toán tử ở đỉnh stack có độ ưu tiên lớn hơn hoặc bằng toán tử đang xét lần lượt đưa vào
biểu thức kết quả và đẩy toán tử đang xét vào stack - Gặp toán tử có độ ưu tiên 6 hoặc
' (' thì đẩy vào stack - Gặp ')' lấy tất cả những toán tử trong stack cho đến khi nào gặp
' (' đầu tiên, đưa sang biểu thức kết quả theo đúng thứ tự và đẩy một kí hiệu ' (' ra khỏi
stack - Nếu duyệt hết biểu thức trung tố, lấy nốt các toán tử trong stack đưa sang biểu
thức kết quả theo đúng thứ tự
3.4 Cách thực hiện
Chuyển đổi biểu thức tiền tố sang hậu tố:

• Duyệt từ trái qua phải.


• Nếu gặp dấu mở ngoặc thì bỏ qua.
• Nếu gặp số thì đưa vào biểu thức mới.
• Nếu gặp toán tử thì đưa vào ngăn xếp.
• Nếu gặp dấu đóng ngoặc thì lấy toán tử ra đưa vào biểu thức mới.
II. HÀNG ĐỢI
1. Cấu trúc dữ liệu hàng đợi là gì ?
Hàng đợi (Queue) là một cấu trúc dữ liệu trừu tượng. Đặc điểm của hàng đợi là FIFO
(first in first out) - có nghĩa là vào trước ra trước. Đặt tên là hàng đợi bởi vì nó là một
cái gì đó tương tự như hàng đợi trong đời sống hàng ngày (xếp hàng).
Khác với ngăn xếp, hàng đợi là mở ở cả hai đầu. Một đầu luôn luôn được sử dụng để
chèn dữ liệu vào (hay còn gọi là sắp vào hàng) và đầu kia được sử dụng để xóa dữ liệu (rời
hàng). Cấu trúc dữ liệu hàng đợi tuân theo phương pháp First-In-First-Out, tức là dữ liệu
được nhập vào đầu tiên sẽ được truy cập đầu tiên.
Trong cấu trúc hàng đợi(queue), ta chỉ có thể thêm các phần tử vào một đầu của queue
(giả sử là cuối), và cũng chỉ có thể xóa phần tử ở đầu còn lại của queue(tạm gọi là đầu).
Như vậy, ở một đầu không thể xảy ra hai hành động thêm và xóa đồng thời.
Danh sách dưới đây là một số hoạt động cơ bản có thể thực hiện trên cấu trúc dữ liệu
hàng đợi:
1.1 Enqueue – Thêm vào cuối hàng đợi
Nếu hàng đợi chưa đầy, chúng ta sẽ thêm phần tử cần thêm vào cuối(rear) của hàng
đợi. Ngược lại, thông báo lỗi.
Các bạn lưu ý, rear là chỉ số của phần tử sẽ được thêm ở lần tiếp theo. Do đó, thêm
xong rồi ta mới tăng rear lên 1 đơn vị. Giá trị rear cần thay đổi nên được truyền theo
tham chiếu.

1.2 Dequeue – Xóa khỏi đầu hàng đợi


Nếu hàng đợi có ít nhất 1 phần tử, chúng ta sẽ tiến hành xóa bỏ phần tử ở đầu
của hàng đợi bằng cách tăng front lên 1 giá trị.
Ở đây, front đang là chỉ số của phần tử sẽ bị xóa rồi. Cho nên chỉ cần tăng là xong,
đó cũng là lý do ta cần truyền tham số front sử dụng tham chiếu.
1.3 Front – Lấy giá trị ở đầu hàng đợi

Hàm này sẽ lấy và trả về giá trị của phần tử đang ở đầu hàng đợi

1.4 Các hàm hỗ trợ khác

Hàm lấy kích thước của Hàng đợi, nói cách khác là số lượng phần tử đang có trên
hàng đợi
2. Hoạt động enqueue trong cấu trúc dữ liệu hàng đợi
Bởi vì cấu trúc dữ liệu hàng đợi duy trì hai con trỏ dữ liệu: front và rear, do đó các
hoạt động của loại cấu trúc dữ liệu này là khá phức tạp khi so sánh với cấu trúc dữ liệu
ngăn xếp.
Dưới đây là các bước để enqueue (chèn) dữ liệu vào trong hàng đợi:

• Kiểm tra xem hàng đợi là có đầy không.


• Nếu hàng đợi là đầy, tiến trình bị lỗi và bị thoát.
• Nếu hàng đợi không đầy, tăng con trỏ rear để trỏ tới vị trí bộ nhớ trống
tiếp theo.
• Thêm phần tử dữ liệu vào vị trí con trỏ rear đang trỏ tới trong hàng đợi.
• Trả về success.

You might also like