Professional Documents
Culture Documents
6.2 Nganxep
6.2 Nganxep
6.2 Nganxep
Trang 2
3
NGĂN XẾP
Tính chất
• Vào trước ra sau (First In Last Out: FILO)
Trang 3
4
NGĂN XẾP
Trang 4
Hai phương pháp biểu diễn ngăn xếp
Biểu diễn liên tục: các phần tử dữ liệu của ngăn xếp được lưu trữ liên tục nhau
trong bộ nhớ (Mảng).
Biểu diễn rời rạc: các phần tử dữ liệu của ngăn xếp được lưu trữ rời rạc nhau
trong bộ nhớ (Danh sách liên kết).
Ví dụ. Biểu diễn ngăn xếp dựa vào mảng.
typedef struct {
int top; //Đỉnh đầu của stack nơi diễn ra mọi thao tác
int node[MAX]; //Dữ liệu lưu trữ trong stack gồm MAX phần tử
} Stack;
top node[top]
top top
node[top]
node[top] Trang 5
CÀI ĐẶT NGĂN XẾP SỬ DỤNG MẢNG
Trang 7
CÀI ĐẶT NGĂN XẾP SỬ DỤNG MẢNG
Trang 8
CÀI ĐẶT NGĂN XẾP SỬ DỤNG MẢNG
Trang 9
CÀI ĐẶT NGĂN XẾP SỬ DỤNG MẢNG
Trang 10
Ví dụ. Cho stack lưu trữ tối đa 5 phần tử. Bắt đầu thực hiện tại trạng thái
rỗng.
top =-1 top =0 top =1 top =2 top =3 top =4
Push(s,9) 9
Push(s,7)
7 7
Push(s,5)
5 5 5
Push(s,3)
3 3 3 3
Push(s,1)
1 1 1 1 1
9 Pop(s)
Pop(s)
7 7
Pop(s)
5 5 5
Pop(s)
3 3 3 3
Pop(s)
1 1 1 1 1
Trang 11
Các thao tác trên stack dựa danh sách liên kết đơn
Stack = { DSLK đơn + [<Add-Top:(Push)>; <Del-Top: (Pop)> ] }
Stack = { DSLK đơn + [<Add-Bottom:(Push)>; <Del-Bottom: (Pop)> ] }
Khử đệ quy
Biểu diễn và chuyển đổi giữa các cách biểu diễn phép toán
Trang 14
THƯ VIỆN STL TRONG C++
<array> <set>
<vector> <multiset>
<deque> <map>
<forward_list> <multimap>
<list> <unordered_set>
<stack> <unordered_multiset>
<queue> <unordered_map>
<priority_queue> <unordered_multimap>
<bitset>
<valarray>
Trang 15
1
6
Ví dụ khai báo và sử dụng stack
#include <iostream>
#include <stack>
#include <conio.h>
using namespace std;
int main ()
{
stack<int> mystack;
for (int i=0; i<5; ++i) mystack.push(i*2);
cout << "Thuc hien phep pop cac phan tu ...";
while(!mystack.empty()){
cout << ' ' << mystack.top();
mystack.pop();
}
cout << '\n';
return 0;
}
Trang 16
1
7
Minh họa các thao tác
Trang 17
1
8
NHẬN XÉT VỀ NGĂN XẾP
Ưu điểm
• Gọi n là số phần tử của ngăn xếp
• Cố push phần tử mới vào ngăn xếp đã đầy sẽ sinh ngoại lệ do cài đặt
(implementation-specific exception)
Trang 18
1
9
Ví dụ: Kiểm tra biểu thức dấu ngoặc cân xứng
Mỗi ngoặc mở “(“, “[“, “{“ phải được cặp với một ngoặc
đóng “)“, “]“, “}“ tương ứng.
Ví dụ
• cân xứng: ( )(( )){([( )])}
• không cân xứng: ((( )(( )){([( )])}
• không cân xứng: )(( )){([( )])}
• không cân xứng: ({[ ])}
• không cân xứng: (
Trang 19
CHUYỂN ĐỔI TRUNG TỐ - HẬU TỐ
a b * c a / b c
a bc * ab / c
abc * ab / c
abc * ab / c
abc * ab / c
Trang 20
Thuật toán chuyển đổi biểu thức trung tố P thành biểu thức hậu tố
Thuật toán tính toán giá trị biểu thức hậu tố?
Bước 1 (Khởi tạo):
stack = ;
Bước 2 (Lặp) :
For each xP do
2.1. Nếu x là toán hạng:
Push( stack, x);
2.2. Nếu x { +, -, *, / }
a) TH2 = Pop(stack, x);
b) TH1 = Pop(stack, x);
c) KQ = TH1 TH2;
d) Push (stack, KQ);
EndFor;
Bước 4(Trả lại kết quả):
Return(Pop(stack)).
Trang 23
Ví dụ: P = 6 2 4 * + 6 2 / 4 + -
4 2 4
2 8 6 3 3 7
* + / / + -
6 6 14 14 14 14 7
Trang 24
BÀI TOÁN: PHẦN TỬ BÊN PHẢI ĐẦU TIÊN LỚN HƠN
MÔ TẢ BÀI TOÁN
Cho dãy số A[] gồm N phần tử. Với mỗi A[i], bạn cần tìm phần tử bên phải
đầu tiên lớn hơn nó. Nếu không tồn tại, in ra -1.
VÍ DỤ:
Dãy A[] = {4, 5, 2, 25}
GIẢI THUẬT:
•Cách làm thông thường: độ phức tạp O(n2)
•Sử dụng Stack: độ phức tạp O(n)
Trang 25
BÀI TOÁN: PHẦN TỬ BÊN PHẢI ĐẦU TIÊN LỚN HƠN
CÀI ĐẶT
void xuly(int a[], int n){
stack<int> st;
int R[n], i;
for(i=n-1;i>=0;i--){
while(!st.empty() && a[i] >= st.top()) st.pop();
if(st.empty()) R[i] = -1;
else R[i] = st.top();
st.push(a[i]);
}
for(i=0;i<n;i++) cout << R[i] << " ";
cout << endl;
}
Trang 26
MỘT SỐ BÀI TOÁN ÁP DỤNG KHÁC
Trang 27