Lưu trữ ngăn xếp Kiểm tra ngăn xếp rỗng Thêm 1 phần tử vào ngăn xếp Lấy 1 phần tử ra khỏi ngăn xếp Lấy thông tin của phần tử đầu ngăn xếp Các thao tác trên ngăn xếp... Ngăn xếp đầy
Trang 1Trường Đại học Khoa học Tự nhiên
Khoa Công nghệ thông tin
KỸ THUẬT LẬP TRÌNH
Trang 4Định nghĩa:
Ngăn xếp là cấu trúc chứa
các đối tượng làm việc theo
cơ chế “vào sau ra trước”
(Last In First Out)
Đối tượng có thể được thêm
vào bất kì lúc nào, nhưng chỉ
có đối tượng vào sau cùng
mới được phép lấy ra khỏi
Trang 5Lưu trữ ngăn xếp
Kiểm tra ngăn xếp rỗng
Thêm 1 phần tử vào ngăn xếp
Lấy 1 phần tử ra khỏi ngăn xếp
Lấy thông tin của phần tử đầu ngăn xếp
Các thao tác trên ngăn xếp
Trang 6Thêm vào đầu danh sách (AddHead): phần tử
mới thêm nằm ở đầu danh sách
Truy xuất danh sách: Truy xuất phần tử nằm
Trang 7Ngăn xếp rỗng khi không chứa phần tử nào (DS rỗng)
Khai báo:
• typedef NODE* STACK;
BOOL IsEmpty (STACK Stack )
Trang 8Ngăn xếp đầy khi không thể cấp phát thêm vùng nhớ
Khi thêm 1 phần tử vào ngăn xếp, nếu không
cấp phát được vùng nhớ -> Thông báo ngăn
xếp đầy
Kiểm tra ngăn xếp đầy
Trang 10int Push ( NODE*& pHead , NODE* x)
Ngăn xếp ban đầu
Ngăn xếp sau khi
Đỉnh
Trang 11Lấy đối tượng ở đầu ngăn xếp ra khỏi ngăn xếp
và trả về giá trị của đối tượng đó
Nếu stack rỗng? -> báo lỗi
Trang 12Thuật toán:
Kiểm tra ngăn xếp rỗng hay không?
Nếu không:
• Ghi nhận giá trị của phần tử ở đầu ngăn xếp
• Xóa phần tử đầu ra khỏi ngăn xếp
Trang 13Data Pop (NODE*& pHead)
{
//kiểm tra ngăn xếp rỗng?
if ( )
return -1 ;
//ghi nhận giá trị đầu ngăn xếp
Data x = pHead -> data;
//xóa đầu ngăn xếp …
//trả về giá trị đã ghi nhận
return _;
Lấy 1 phần tử ra khỏi ngăn xếp
Trang 14Chỉ lấy giá trị của phần tử đầu mà không hủy nó
Trang 15Cho biết nội dung của stack sau mỗi thao tác
trong dãy:
EAS*Y**QUE***ST***I*ON
Một chữ cái tượng trưng cho thao tác thêm chữ cái đó vào stack, dấu * tượng trưng cho thao tác lấy nội dung một phần tử trong stack in lên màn hình
Cho biết kết quả xuất ra màn hình sau khi hoàn tất chuỗi trên?
Bài tập
Trang 16Cho biết nội dung của stack và giá trị của các
biến sau khi thực hiện các thao tác sau: A= 5, B
d Pop và lưu trữ vào A
e Pop và lưu trữ vào B
Bài tập
Trang 17Bài tập: cài đặt lại các thao tác khi lưu trữ stack bằng mảng 1 chiều (sinh viên tự tìm hiểu)
Các thao tác trên Mảng 1 chiều
Trang 18Biểu diễn số:
Hệ thập phân: 271 = 2 * 10 2 + 7 * 10 1 + 1 * 10 0
Hệ nhị phân:
110110 = 1* 2 5 + 1 * 2 4 + 0 * 2 3 + 1 * 2 2 + 1 * 2 1 + 0 * 2 0
Qui tắc đổi từ thập phân sang cơ số n:
Chia liên tiếp số cần đổi cho n
Lấy số dư (các số <n) theo chiều ngược lại
Đổi cơ số
Trang 19Ví dụ: đổi số 215 sang nhị phân
Trang 20Nhận xét? Số dư tạo ra sau thì được hiển thị
trước -> phù hợp với cơ chế hoạt động của stack
-> dùng stack để lưu trữ các số dư sau mỗi
Trang 21 Giải thuật chuyển đổi số thập phân n sang cơ số
//tính số dư của phép chia
//push số dư vào stack
Trang 22Bài tập: hãy biến đổi số thập phân 347 sang cơ
số 3 Minh họa tình trạng stack được sử dụng
để lưu trữ các số dư trong quá trình chuyển đổi.Đổi cơ số
Trang 23Biểu thức dạng trung tố: dấu của các phép
toán hai ngôi luôn được đặt giữa 2 toán hạng
Ví dụ: A + B * C A + B * C - D
(A+B) * C (A + B )* (C – D)
Qui định thứ tự ưu tiên của các phép toán
Dùng dấu ngoặc để phân biệt thứ tự thực
hiện
Ký pháp Ba Lan
Trang 24Trung tố Tiền tố
A + B * C - D - + A* B C D (A + B )* (C – D) * + A B – C D
Trung tố Hậu tố
A + B * C - D A B C * + D - (A + B )* (C – D) A B + C D - *
Trang 25Biểu diễn biểu thức bằng 1 stack dạng danh
Tính giá trị biểu thức dạng hậu tố
Trang 2626
Giải thuật:
Đọc biểu thức từ trái qua phải:
Trong khi chưa hết biểu thức:
• Nếu kí tự là toán hạng thì giữ lại giá trị
• Nếu là toán tử thì 2 giá trị vừa được giữ lại sẽ được
lấy ra và tính theo toán tử vừa được đọc; lưu lại giá trị vừa được tính
Giá trị cuối cùng được lưu lại là giá trị của
biểu thức
Tính giá trị biểu thức dạng hậu tố
Trang 27Nhận xét: 2 toán hạng được đọc sau được kết hợp với toán tử đọc trước -> giá trị nào vào sau
thì được xử lý trước
=> Phù hợp với cách hoạt động của stack
Tính giá trị biểu thức dạng hậu tố
Trang 293.3 w = z (x) y //tính giá trị w theo toán tử x
Tính giá trị biểu thức dạng hậu tố
Trang 30Nhận xét:
Nếu xuất hiện dấu „(„ thì phải có „)‟ tương ứng
Dấu mở ngoặc gặp trước sẽ được đóng
ngoặc sau
Khi gặp toán tử, phải chờ xác định toán hạng thứ 2 thì mới đặt toán tử sau toán hạng này Chuyển trung tố sang hậu tố
Dùng stack để lưu trữ dấu „(„ „)‟ và các toán tử
Trang 31 Mã giả: P là biểu thức trung tố ban đầu, Q là biểu
thức kết quả dạng hậu tố
0.1 Push(‘(‘);
0.2 Thêm ‘)’ vào cuối P
while (chưa hết biểu thức P)
Trang 324 if (x là toán tử)
4.1 while( thứ tự ưu tiên (toán tử đầu
stack) >= x) 4.1.1 w = Pop();
Trang 33Ví dụ 1: P = ( A + B ) * ( C - ( D + A ) )
Chuyển trung tố sang hậu tố
( (
+ ( (
+ ( ( (
* (
(
* (
(
* (
- (
* (
(
- (
* (
(
- (
* (
+ (
- (
* (
+ (
- (
* (
- (
* (
* (
Trang 34Ví dụ 2: đổi biểu thức trung tố
P = A + (B * C – (D / E ^ F) * G) * H
sang biểu thức dạng hậu tố
Chuyển trung tố sang hậu tố
Trang 35Trong trình biên dịch, stack được sử dụng để
lưu môi trường các thủ tục
Dùng trong một số bài toán của lý thuyết đồ thị
Khử đệ qui đuôi
Ứng dụng khác của stack
Trang 36Cho biểu thức dạng trung tố P:
A / ( B + C ) + D * ( E + F )
a Hãy viết biểu thức dạng hậu tố ứng với P
b Minh họa tình trạng của stack qua các bước
thực hiện tính biểu thức hậu tố với A = 12, B =
7, C = 3, D = 2, E = 1, F = 5
Bài tập 1
Trang 37Giới thiệu:
Là cấu trúc chứa các đối tượng làm việc theo qui tắc vào trước ra trước (FIFO)
Các đối tượng có thể được thêm vào hàng
đợi bất kì lúc nào nhưng chỉ có đối tượng
thêm vào đầu tiên mới được lấy ra khỏi hàng đợi
Việc thêm vào diễn ra ở cuối, việc lấy ra diễn
Hàng đợi (Queue)
1 3 6 5 2
Trang 38Lưu trữ hàng đợi
Thêm 1 đối tượng vào cuối hàng đợi
Lấy đối tượng ở đầu ra khỏi hàng đợi
Kiểm tra hàng đợi rỗng
Lấy thông tin của đối tượng ở đầu hàng đợi
Các thao tác trên hàng đợi
Trang 39Khai báo hàng đợi như một DSLK với phần tử đầu (pHead) và đuôi (pTail)
Phần tử đầu: nơi lấy dữ liệu hàng đợi ra
Phần tử đuôi: nơi thêm phần tử vào
Lưu trữ hàng đợi bằng DSLK
Trang 40Hàng đợi rỗng khi không có phần tử nào (DS
rỗng)
Khai báo:
BOOL IsEmpty (NODE* pHead)
Trang 41Hàng đợi đầy khi không thể cấp phát thêm vùng nhớ
Khi thêm 1 phần tử vào hàng đợi, nếu không
cấp phát được vùng nhớ -> Thông báo hàng đợi đầy
Kiểm tra hàng đợi đầy
Trang 42Khai báo:
int EnQueue ( QUEUE &Queue, NODE* x)
Giải thuật:
Tương tự thao tác thêm đuôi
Nếu không thêm được (do không cấp phát
được vùng nhớ) trả về giá trị cho biết hàng
đợi đầy
Thêm phần tử vào cuối hàng đợi
Trang 43int EnQueue ( QUEUE &Queue, NODE* x)
Trang 44Khai báo:
Data DeQueue ( QUEUE & Queue)
Giải thuật:
• Ghi nhận giá trị của phần tử ở đầu hàng đợi
• Xóa phần tử đầu ra khỏi hàng đợi
• Trả về giá trị đã ghi nhận Lấy phần tử đầu ra khỏi hàng đợi
Trang 45Data DeQueue( QUEUE & Queue)
{
//kiểm tra stack rỗng?
if ( )
return NULLDATA ;
//ghi nhận giá trị đầu Queue
Data x = Queue.pHead -> data;
//xóa đầu Queue…
//trả về giá trị đã ghi nhận
return _;
Lấy 1 phần tử ra khỏi stack
Trang 46Chỉ lấy thông tin của đối tượng đầu hàng đợi mà không hủy đối tượng khỏi hàng đợi
Khai báo:
Data Front ( QUEUE Queue)
Giải thuật:
Kiểm tra hàng đợi rỗng?
Trả về giá trị của phần tử đầu hàng đợi
Lấy thông tin đầu hàng đợi
Trang 47Sinh viên tự nghiên cứu
Lưu trữ hàng đợi bằng mảng 1 chiều
Trang 48Bộ đệm bàn phím của máy tính
Xử lý các lệnh trong máy tính: hàng đợi thông
điệp trong Windows, hàng đợi tiến trình …
Sử dụng giải 1 số bài toán lý thuyết đồ thị
Ứng dụng của hàng đợi
Trang 49Cho hàng đợi ban đầu như sau: (hàng đợi có tối đa 6 phần tử)
Vẽ tình trạng của hàng đợi tương ứng với mỗi lần thực hiện thao tác sau:
a Bổ sung E vào hàng đợi
b Loại 2 phần tử khỏi hàng đợi
c Bổ sung I, J, K vào hàng đợi
d Loại 2 phần tử khỏi hàng đợi
Bài tập 2
Trang 50Hỏi và đáp