NGĂN XẾP VÀ HÀNG ĐỢI
STACK VÀ QUEUE
Định nghĩa:
Stack là một danh sách đặc biệt mà phép thêm
vào hoặc loại bỏ một phần tử chỉ thực hiện tại
một đầu gọi là đỉnh (Top) của Stack.
đỉnh
đáy
Như vậy, stack hoạt động theo
cơ chế vào sau ra trước (Last In
First Out).
Do đó stack còn được gọi là
danh sách kiểu LIFO.
Khởi tạo stack:
• Tạo stack bằng cách khai báo mảng một
chiều S với kích thước tối đa là N và biến
nguyên t cho biết chỉ số của đỉnh stack.
• Như vậy, stack hiện có t+1 phần tử và
có thể chứa tối đa N phần tử.
• Khai báo:
Data S[N];
int
t;
Lệnh t=-1 sẽ tạo ra một stack rỗng.
Ví dụ:
s
1
7
S[0]
S[1]
N=6 ; t=3
1
0
S[2]
S[3]
Các phép toán trên Stack:
•
•
•
•
Kiểm tra stack rỗng hay không.
Kiểm tra stack đầy hay không.
Thêm một phần tử vào stack.
Xem thông tin của phần tử ở đỉnh
stack.
• Trích thông tin và hủy phần tử ở
đỉnh stack.
Kiểm tra stack rỗng hay không:
int Empty()
{
if (t== -1)
return 0;
else
return 1;
}
// stack rỗng
Kiểm tra stack đầy hay không:
int Full()
{
if ( t==N-1 )
return 1;
else
return 0;
}
// stack đầy
Thêm phần tử x vào stack:
void Push( Data x, int& t )
{
if ( t
{
t++;
S[t]=x;
}
else cout<<“Stack đầy”;
}
Xem thông tin của phần tử ở đỉnh stack
Data Top( )
{
if ( t>-1 )
// stack khác rỗng
return S[t];
else cout<<“”stack rỗng’’;
return 0;
}
Trích thông tin
và hủy phần tử ở đỉnh stack
Data Pop(int& t)
{
if ( t>-1 ) // stack khác rỗng
{
Data tam=S[t];
t--;
return tam;
}
else cout<<“Stack rỗng”;
return 0;
}
Ứng dụng của stack:
Đổi cơ số từ thập phân sang nhị
phân.
Tính giá trị của một biểu thức ở
dạng hậu tố.
Đổi 17 sang hệ nhị phân
17 2
1 8 2
2
4
0
2
2
0
0 1 2
1 0
Đổi sang hệ nhị phân:
void change( int n )
{
int r,m=n;
while (m>0)
{
r = m%2;
Push( r, t );
m = m/2;
}
while ( Empty()!=0 )
cout<< Pop(t);
}
Tính giá trị của: 512+4*+3+ =?
Ký tự
Thao tác
Trạng thái stack
5
Push 5
5
1
Push 1
5, 1
2
Push 2
5, 1, 2
+
Tính 1 + 2
Push 3
5, 3
4
Push 4
5, 3, 4
*
Tính 3 * 4
Push 12
5, 12
+
Tính 12 + 5
Push 17
17
3
Push 3
17, 3
+
Tính 17 + 3
Push 20
20
Đổi từ trung tố
sang hậu tố
Ký tự
3+4*2/(1-5)
Thao tác
Stack
Chuỗi hậu tố
3
Ghi 3 vào k.quả
3
+
Push +
+
4
Ghi 4 vào k.quả
34
*
Push *
+*
2
Ghi 2 vào kquả
342
/
Lấy * ra khỏi stack, + /
ghi vào k.quả, push /
342*
(
Push (
+/(
342*
1
Ghi 1 vào k.quả
+/(
342*1
-
Push -
+/(-
342*1
5
Ghi 5 vào k.quả
+/(-
342*15
)
Pop cho đến khi lấy + /
được (, ghi các toán
tử pop được ra k.quả
342*15-
Pop tất cả các toán
tử ra khỏi ngăn xếp
và ghi vào kết quả
342*15– /+
Ý tưởng:
Nếu gặp một toán hạng (con số hoặc biến) thì ghi nó vào
chuỗi kết quả (chuỗi kết quả là biểu thức trung tố).
Nếu gặp dấu mở ngoặc, đưa nó vào stack.
Nếu gặp một toán tử (gọi là x1 ), thực hiện hai bước sau:
Chừng nào còn có một toán tử x2 ở đỉnh ngăn xếp và độ ưu
tiên của x1 nhỏ hơn hay băng độ ưu tiên của x2 thì lấy x2 ra
khỏi ngăn xếp và ghi vào kết quả.
Push x1 vào ngăn xếp
Nếu gặp dấu đóng ngoặc thì cứ lấy các toán tử trong ngăn
xếp ra và ghi vào kết quả cho đến khi lấy được dấu mở
ngoặc ra khỏi ngăn xếp.
Khi đã duyệt hết biểu thức trung tố, lần lượt lấy tất cả toán
hạng (nếu có) từ ngăn xếp ra và ghi vào chuỗi kết quả.
Hàng đợi (QUEUE)
Đònh nghóa:
H àng đợi là một vật
chứa các đối tượng làm
việc theo cơ chế FIFO:
Nghóa là việc thêm một
đối tượng vào hàng đợi
hoặc lấy một đối tượng ra
khỏi hàng đợi được thực
hiện theo cơ chế “vào
Ví dụ:
Xếp hàng đợi khám bệnh.
Đợi mua vé xe lửa.
Xếp hàng vào phòng thi…
Ai tới trước thì được khám
trước, được mua vé
trước và người ở đầu hàng
được vào phòng trước.
Biểu diễn dùng
mảng:
Ta có thể tạo hàng đợi bằng cách sử
dụng một mảng 1 chiều với kích thước
tối đa là N.
Phần tử nằm ở đầu hàng đợi có chỉ
số f và phần tử nằm ở cuối hàng đợi
có chỉ số r.
A
B C
D
r
f
A
E
B C
D
E
G
r
f
B C
f
D
E
G
r
Q biểu diễn bằng mảng tịnh tiến
Khụỷi taùo Queue baống maỷng
tũnh tieỏn
Data Q[N]
int f = 0;
int r = -1;
Kiểm tra hàng đợi
rỗng
• Thuật toán:
Nếu f > r thì hàng đợi rỗng
ngược lại hàng đợi không rỗng.
int Emty()
{
if ( f > r) retunr 0; //hàng đợi rỗng.
else return 1; // hàng đợi không
rỗng.
}
Kiểm tra hàng đợi
đầy:
• Thuật toán:
đầy.
Nếu (r – f +1) = N thì hàng đợi
Ngược lại hàng đợi không đầy.
int Full()
{
if ((r- f+ 1) = N) return 1; //hàng đợi
đầy.
else return 0; // hành đợi không đầy.
}