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 class Stack { public:

//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 Error_code Stack:: top(Entry &item) {

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

ươ