Ấ
C U TRÚC D LI U VÀ I THU T GI
Ữ Ệ Ả
Ậ
Ch
ng 2: Stack
ươ
Mô t
stack
ả
ộ ấ
M t stack là m t c u trúc d ữ ộ li u mà vi c thêm vào và ệ ệ i lo i b đ c th c hi n t ệ ạ ạ ỏ ượ m t đ u (g i là đ nh – top ỉ ọ ộ ầ c a stack). ủ
Là m t d ng vào sau ra
ự
ộ ạ c – LIFO (Last In First
2
Ch
ng 2: Stack
ươ
tr ướ Out)
Ví d v stack ụ ề
Stack r ng:ỗ
Đ y (push) Q vào:
Q
A
Đ y A vào:
ẩ
Q
L y (pop) ra m t => đ
ẩ
A
Q
L y ra m t => đ
c A: ấ ộ ượ
Q
3
Ch
ng 2: Stack
ươ
c Q và stack r ng: ấ ộ ượ ỗ
ng d ng: Đ o ng
c danh sách
Ứ
ụ
ả
ượ
Yêu c u: Đ o ng ầ i thu t: Gi
c m t danh sách nh p vào ả ượ ậ ộ
ả ậ
1. L p l ặ ạ
ị ộ i n l n ậ
ẩ
ặ
stack ầ 1.1. Nh p vào m t giá tr 1.2. Đ y nó vào stack 2. L p khi stack ch a r ng ư ỗ ị ừ ộ ấ
4
Ch
ng 2: Stack
ươ
2.1. L y m t giá tr t 2.2. In ra
Đ o ng
c danh sách – Ví d
ả
ượ
ụ
ầ
ố Nh p 1ậ
Nh p 5ậ
Nh p 7ậ
Nh p 3ậ
C n nh p 4 s vào ậ Ban đ uầ
3 7
7
5 1
5 1
5 1
1
L y ra => 3
L y ra => 7
ấ
ấ
L y ra => 5
L y ra => 1
ấ
ấ
Stack đã r ngỗ Ng ngừ
3
7
7
5 1
5 1
5 1
1
5
Ch
ng 2: Stack
ươ
Đ o ng
c danh sách – Mã C++
ả
ượ
#include
using namespace std;
s d ng STL ử ụ (Standard Template Library)
ữ ệ
ể
ộ
khai báo m t stack có ki u d li u c a các phân t
bên trong là double
ử
ủ
đ y m t s vào trong stack
ộ ố
ẩ
ki m tra xem stack có khác r ng không
ể
ỗ
ủ
l y giá tr trên đ nh c a stack ra, ỉ ị ấ stack không đ iổ
int main( ) {
int n;
double item;
stack numbers;
cout << "Bao nhieu so nhap vao? "
cin >> n;
for (int i = 0; i < n; i++) {
cin >> item;
numbers.push(item);
}
while (!numbers.empty( )) {
cout << numbers.top( ) << " ";
numbers.pop( );
} }
ỏ
ị
ỉ
là giá tr k ti p
l y giá tr trên đ nh c a stack ra kh i stack, ấ ủ đ nh c a stack bây gi ờ ỉ
ị ế ế
ủ
6
Ch
ng 2: Stack
ươ
Ki u tr u t
ng (abstract data type)
ừ ượ
ể
ể ợ
ủ ậ ầ ợ ị
ĐN2: M t dãy c a ki u T
ĐN1: M t ki u (type) ộ m t t p h p ộ ậ m i thành ph n c a t p h p này là các giá tr (value) ỗ Ví d : int, float, char là các ki u c b n ể
ơ ả ể
ụ ộ
ủ có chi u dài b ng 0 là r ng ằ có chi u dài n (n>=1): b th t (Sn-1, t) ỗ ộ ứ ự ề ề
Sn-1: dãy có chi u dài n-1 thu c ki u T t là m t giá tr thu c ki u T. ộ ị
ể ề ộ
7
Ch
ng 2: Stack
ươ
ể ộ
Stack tr u t
ng
ừ ượ
M t stack ki u T:
ạ ể
create)
ỗ
push) ủ ỉ
pop) ủ ỉ ị
8
Ch
ng 2: Stack
ươ
ộ ể M t dãy h u h n ki u T ộ ữ M t s tác v : ụ ộ ố 1. Kh i t o stack r ng ( ỗ empty) 2. Ki m tra r ng ( 3. Đ y m t giá tr vào trên đ nh c a stack ( ị ộ 4. B giá tr đang có trên đ nh c a stack ( 5. L y giá tr trên đ nh c a stack, stack không đ i ( ủ ở ạ ể ẩ ỏ ấ ỉ ị ổ top)
Thi
t k stack
ế ế
enum Error_code {fail, success, overflow, underflow};
template
//constructor
ỗ
ng th c c n thi Stack(); bool empty() const; Error_code push(const Entry &item); Error_code pop(); ỏ Error_code top(Entry &item); ấ //khai báo m t s ph ộ ố //ki m tra r ng ể //đ y item vào ẩ trên đ nh //b ph n t ỉ ầ ử //l y giá tr trên đ nh ỉ ị t khác ầ ươ ứ ế
private:
//khai báo d li u và hàm ph tr ch này ụ ợ ữ ệ ỗ
9
Ch
ng 2: Stack
ươ
};
Thi
t k các ph
ng th c
ế ế
ươ
ứ
i thì tr v
template
bool Stack::empty() const;
Pre: Không có
Post: Tr v giá tr
ả ề
ị true n u stack hi n t
ệ ạ
ế
i là r ng, ng ỗ
c l ượ ạ
ả ề false
ệ ạ
ầ
c thêm vào đ nh c a stack. ỉ
ủ
i tr v giá tr
c l
template
Error_code Stack::push(const Entry &item);
Pre: Không có
Post: N u stack hi n t
ế
Ng
ượ ạ ả ề
i không đ y, item s đ ẽ ượ ể
ủ
ị overflow c a ki u Error_code và stack không đ i. ổ
i không r ng, đ nh c a stack hi n t
i s b h y b .
ệ ạ
ệ ạ ẽ ị ủ
ủ
ỗ
ỏ
ỉ
i tr v giá tr
c l
template
Error_code Stack::pop() const;
Pre: Không có
Post: N u stack hi n t
ế
Ng
ượ ạ ả ề
ị underflow c a ki u Error_code và stack không đ i. ổ
ủ
ể
i không r ng, đ nh c a stack hi n t
c chép vào tham
ủ
ệ ạ ẽ ượ
template
Error_code Stack::top(Entry &item) const;
Pre: Không có
Post: N u stack hi n t
ế
bi n item. Ng
ế
i s đ ệ ạ ỉ ỗ ị fail c a ki u Error_code. i tr v giá tr c l ượ ạ ả ề
ủ
ể
10
Ch
ng 2: Stack
ươ
Hi n th c stack liên t c
ự
ụ
ệ
11
Ch
ng 2: Stack
ươ
Khai báo stack liên t cụ
const int maxstack = 10;
//small number for testing
template
class Stack {
public:
Stack( ); bool empty( ) const; Error_code pop( ); Error_code top(Entry &item) const; Error_code push(const Entry &item);
private:
int count; Entry entry[maxstack];
};
12
Ch
ng 2: Stack
ươ
vào stack
Đ y m t ph n t ộ
ầ ử
ẩ
Gi
ả
ỉ
ủ ứ ỉ
7
top
5
count=3 count=2
1
13
Ch
ng 2: Stack
ươ
i thu t: ậ 1. N u còn ch tr ng trong stack ỗ ố ế 1.1. Tăng v trí đ nh lên 1 ị 1.2. Ch a giá tr vào v trí đ nh c a stack 1.3. Tăng s ph n t ị lên 1 ị ầ ử ố
B ph n t
ầ ử
trên đ nh stack ỉ
ỏ Gi
ả
i thu t: ậ 1. N u còn ph n t ế
top
7
5
count=2 count=3
1
14
Ch
ng 2: Stack
ươ
đi 1 trong stack ầ ử 1.1. Gi m v trí đ nh đi 1 ị ả 1.2. Gi m s ph n t ố ả ỉ ầ ử
- Mã C++
Thêm/B ph n t ỏ
ầ ử
template
Error_code Stack:: push(const Entry &item) {
if (count >= maxstack)
return overflow;
else
entry[count++] = item;
return success;
}
template
Error_code Stack:: pop() {
if (count == 0)
return underflow;
else
count--; return success;
}
15
Ch
ng 2: Stack
ươ
L y giá tr trên đ nh stack
ỉ
ị
ấ Gi
ả
trong stack
Mã C++:
i v trí đ nh i thu t: ậ 1. N u còn ph n t ầ ử ế 1.1. Tr v giá tr t ả ề ị ạ ị ỉ
template
if (count == 0)
return underflow;
else
item = entry[count - 1];
return success;
16
Ch
ng 2: Stack
ươ
}
Reverse Polish Calculator
Mô t
ả
ọ ượ ướ
bài toán: Các toán h ng đ ạ Khi đ c vào toán t stack, tính toán ọ c và đ y vào stack ừ ạ
Thi
c đ c vào tr ẩ , l y hai toán h ng ra t này, r i đ y k t qu vào stack ả ế ử ấ ồ ẩ
ề
ứ ộ
ng i dùng ạ ậ ệ ườ
17
Ch
ng 2: Stack
ươ
v i toán t ử ớ t k ph n m m: ầ ế ế C n m t stack đ ch a toán h ng ể ầ C n hàm get_command đ nh n l nh t ừ ầ C n hàm do_command đ th c hi n l nh ệ ệ ầ ể ể ự
ế ế ứ
ị ồ ẩ ộ
‘+’, ‘-’, ‘*’, ‘/’: l y 2 giá tr trong stack, tính toán và ị
‘=’: in đ nh c a stack ra
ấ đ y k t qu vào stack ả ủ ng trình
Reverse Polish Calculator t k ch c năng – Thi T p l nh: ậ ệ ‘?’: đ c m t giá tr r i đ y vào stack ọ Toán t ử ế ẩ Toán t ử ‘q’: k t thúc ch ế
18
Ch
ng 2: Stack
ươ
ỉ ươ
Reverse Polish Calculator – Ví dụ
5
8
3
3
5 3
Đ y 8 vào
?ử
?ử
ẩ
Ban đ uầ
+ử
Toán t Nh p vào 3 ậ
Toán t Nh p vào 5 ậ
ấ
Toán t L y ra 5 và 3 Tính 3 + 5 => 8
2
2
8
8
16 16
16
Đ y vào 16
?ử
=ử
*ử
ẩ
Toán t In ra 16
Toán t Nh p vào 2 ậ
ấ
Toán t L y ra 2 và 8 Tính 8 * 2 => 16
19
Ch
ng 2: Stack
ươ
Tính toán bi u th c: 3 5 + 2 * = ứ ể
Reverse Polish Calculator – Hàm get_command
char get command( ) {
char command;
bool waiting = true;
cout << "Select command and press < Enter > :";
while (waiting) {
cin >> command;
command = tolower(command);
if (command == ‘?’ || command == ‘=‘ || command == ‘+’ ||
command == ‘−’|| command == ‘*’ || command == ‘/’ ||
command == ‘q’) waiting = false;
else {
cout << "Please enter a valid command:" << endl
<< "[?]push to stack [=]print top" <
20
Ch
ng 2: Stack
ươ
Reverse Polish Calculator –
Gi
i thu t tính toán v i toán t
ớ
ậ
ả
ử
Algorithm Op_process
ạ
Input: toán t
ử op, stack ch a các toán h ng
ứ
Output: stack ch a các toán h ng sau khi tính xong toán t
ứ
ạ
ử op
ỗ
ế
trên đ nh stack
ỉ
ỗ
ẩ
c l
i
ượ ạ
i và thoát
ỗ
1. N u stack không r ng
1.1. L y đ nh stack ra thành p
ấ
ỉ
1.2. B ph n t
ầ ử
ỏ
1.3. N u stack r ng
ế
1.3.1. Đ y p ng
1.3.2. Báo l
1.4. L y đ nh stack ra thành q
ỉ
ấ
1.5. B ph n t
trên đ nh stack
ỉ
ầ ử
ỏ
1.6. Tính toán (q op p)
1.7. Đ y k t qu vào stack
ế
ẩ
ả
End Op_process
21
Ch
ng 2: Stack
ươ
Reverse Polish Calculator –
Mã C++ cho toán t
c ng
ử ộ
ỗ
ị
if (numbers.top(p) == underflow)
cout << "Stack r ng";
else {
numbers.pop( );
if (numbers.top(q) == underflow) {
cout << "Stack ch có 1 tr ”;
ỉ
numbers.push(p);
}
else {
numbers.pop( );
if (numbers.push(q + p) == overflow)
cout << "Stack đ y”;ầ
}
}
22
Ch
ng 2: Stack
ươ
Reverse Polish Calculator –
Ch
ng trình chính
ươ
#include "stack.cpp"
//prototype
void introduction( );
void instructions( );
char get_command( );
bool do_command(char command, Stack &numbers);
int main( ) {
Stack stored_numbers;
introduction( );
instructions( );
while (do_command(get_command( ), stored_numbers));
}
//implementation
…
23
Ch
ng 2: Stack
ươ
Reverse Polish Calculator –
Hàm do_command
bool do_command(char command, Stack &numbers) {
double p, q;
switch (command) {
case '?’:
cout << "Enter a real number: " << flush; cin >> p;
if (numbers.push(p) == overflow)
cout << "Warning: Stack full, lost number" << endl; break;
case '=‘:
if (numbers.top(p) == underflow) cout << "Stack empty" << endl;
else cout << p << endl; break;
24
// Add options for further user commands.
case ‘q’: cout << "Calculation finished.\n"; return false;
}
return true;
}
Ch
ng 2: Stack
ươ
20
Ch
ng 2: Stack
ươ
Reverse Polish Calculator – Gi
i thu t tính toán v i toán t
ớ
ậ
ả
ử
Algorithm Op_process
ạ
Input: toán t ử op, stack ch a các toán h ng ứ Output: stack ch a các toán h ng sau khi tính xong toán t
ứ
ạ
ử op
ỗ
ế
trên đ nh stack ỉ ỗ
ẩ
c l i ượ ạ i và thoát
ỗ
1. N u stack không r ng 1.1. L y đ nh stack ra thành p ấ ỉ 1.2. B ph n t ầ ử ỏ 1.3. N u stack r ng ế 1.3.1. Đ y p ng 1.3.2. Báo l 1.4. L y đ nh stack ra thành q ỉ ấ 1.5. B ph n t trên đ nh stack ỉ ầ ử ỏ 1.6. Tính toán (q op p) 1.7. Đ y k t qu vào stack ế
ẩ
ả
End Op_process
21
Ch
ng 2: Stack
ươ
Reverse Polish Calculator – Mã C++ cho toán t
c ng
ử ộ
ỗ
ị
if (numbers.top(p) == underflow) cout << "Stack r ng"; else { numbers.pop( ); if (numbers.top(q) == underflow) { cout << "Stack ch có 1 tr ”; ỉ numbers.push(p); } else { numbers.pop( ); if (numbers.push(q + p) == overflow) cout << "Stack đ y”;ầ } }
22
Ch
ng 2: Stack
ươ
Reverse Polish Calculator – Ch
ng trình chính
ươ
#include "stack.cpp"
//prototype
void introduction( );
void instructions( );
char get_command( );
bool do_command(char command, Stack &numbers);
int main( ) {
Stack stored_numbers;
introduction( );
instructions( );
while (do_command(get_command( ), stored_numbers));
} //implementation …
23
Ch
ng 2: Stack
ươ
Reverse Polish Calculator – Hàm do_command
bool do_command(char command, Stack &numbers) { double p, q; switch (command) { case '?’: cout << "Enter a real number: " << flush; cin >> p; if (numbers.push(p) == overflow) cout << "Warning: Stack full, lost number" << endl; break; case '=‘: if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else cout << p << endl; break;
24
// Add options for further user commands. case ‘q’: cout << "Calculation finished.\n"; return false; } return true; }
Ch
ng 2: Stack
ươ