Tải bản đầy đủ (.ppt) (62 trang)

Mô tả kiểu dữ liệu trừu tượng stack pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.31 MB, 62 trang )

Mô tả kiểu dữ liệu
trừu tượng stack
Nội dung

Mô tả kiểu dữ liệu trừu tượng: stack

Cài đặt

Các ứng dụng minh họa

Phân tích cú pháp: XHTML, C++

Lời gọi hàm

Cú pháp nghịch đảo Balan
Mô tả

Stack là một cấu trúc dữ liệu hoạt động theo cơ
chế last-in—first-out (LIFO):

Mỗi lần chỉ được đưa vào hoặc lấy ra khỏi stack
một đối tượng

Đối tượng được lấy ra khỏi stack là đối tượng
được chèn vào stack mới nhất

Các thao tác chèn và lấy ra được gọi là push và
pop
Mô tả
Có hai lỗi liên quan với kiểu dữ liệu trừu tượng này:


pop một stack rỗng hoặc

Chưa định nghĩa vị trí top của một stack rỗng
A B C D M N
top
Hiện thực

Chỉ có thể chèn vào hoặc lấy ra trong
thời gian O(1) tại cuối dãy

Vì vậy, có thể hiện thực stack bằng việc
push và pop ở cuối dãy:
0 1 2 3 4 6 8 11 15 17 18 22
top
Errors

Nếu mảng bị đầy, ta có các tùy chọn:
1. Tăng kích thước mảng,
2. Thông báo lỗi,
3. Bỏ qua phần tử đang push vào Stack,
4. Cho tiến trình ngưng lại chờ đến khi gặp thao
tác pop ra từ Stack
Stack, sử dụng mảng
Giả sử Stack chứa các phần tử kiểu nguyên
Khai báo cấu trúc Stack
Typedef struct Stack
{
int *arrStack; // mảng chứa các phần tử
int max; // số phần tử tối đa
int top; // vị trí đỉnh Stack

}
Stack, sử dụng mảng

Thao tác khởi tạo Stack rỗng
int Init(Stack &s, int maxItems)
{
s.arrStack = new int(maxItems);
if (s.arrStack == NULL)
return 0; // không cấp phát được bộ nhớ
s.max = maxItems;
s.top = -1; // chưa có phần tử nào trong
Stack
return 1; // khởi tạo thành công
}
Stack, sử dụng mảng

Thao tác kiểm tra Stack rỗng
int IsEmpty(const Stack &s)
{
if (s.top == -1) return 1; // Stack
rỗng
return 0; // Stack
không rỗng
}
Stack, sử dụng mảng

Thao tác kiểm tra Stack đầy
int IsFull(const Stack &s)
{
if (s.top == s.max -1)

return 1; // Stack đầy
return 0; // Stack chưa
đầy
}
Stack, sử dụng mảng

Thao tác Push: thêm 1 phần tử vào đỉnh Stack
int Push(Stack &s, int newItem)
{
if (IsFull(s))
return 0; // Stack đầy, không thêm vào được
s.top++;
s.arrStack[s.top] = newItem;
return 1; // thêm thành công
}
Stack, sử dụng mảng

Thao tác Pop: lấy ra 1 phần tử từ đỉnh Stack
int Pop(Stack &s, int &outItem)
{
if (IsEmpty(s))
return 0; // Stack rỗng, không lấy ra được
outItem = s.arrStack[s.top];
s.top ;
return 1; // lấy ra thành công
}
Stack, sử dụng danh sách
liên kết
khai báo cấu trúc 1 phần tử trong stack
Typedef struct tagSTACK_NODE

{
int Data;
tagSTACK_NODE *next;
} S_Node;
khai báo cấu trúc stack
Typedef S_Node *SList;
Stack, sử dụng danh sách
liên kết

Thao tác khởi tạo Stack rỗng
void InitStack(SList s)
{
s = NULL;
}
Stack, sử dụng danh sách
liên kết

Thao tác kiểm tra Stack rỗng
int IsEmpty(SList s)
{
if(s == NULL)
return 1; // Stack rỗng
return 0; // Stack không rỗng
}
Stack, sử dụng danh sách
liên kết

Thao tác Push: thêm 1 phần tử vào đỉnh Stack
int Push(SList s, int newItem)
{

SList pNew = new S_Node;
pNew → Data = newItem;
pNew → next = s;
s = pNew;
return 1; // thêm thành công
}
Stack, sử dụng danh sách
liên kết

Thao tác Pop: lấy ra 1 phần tử từ đỉnh Stack
int Pop(SList s, int &outItem)
{
if (IsEmpty(s))
return 0; // Stack rỗng, không lấy ra được
outItemp = s → Data;
SList temp = s;
s = s → next;
delete temp;
return 1; // lấy ra thành công
}
Applications

phân tích cú pháp (parsing code):

Kiểm tra các dấu ngoặc đơn

XML (e.g., XHTML)

Trong trình biên dịch (thông dịch), khi thực hiện
các thủ tục, Stack được sử dụng để lưu môi

trường của các thủ tục

Khử đệ qui

Tổ chức lưu vết các quá trình tìm kiếm theo
chiều sâu và quay lui.

Xử lý các thao tác undo/redo

Cú pháp nghịch đảo Balan
Applications

Cách giải quyết vấn đề:

Giải quyết một vấn đề có thể dẫn đến nhiều bài
toán khác nhau

Một bài toán có thể là kết quả của những bài
toán nhỏ hơn.

Khi các bài toán nhỏ hơn đã được giải quyết,
điều ta quan tâm là trở về bài toán ban đầu
Parsing

Hầu hết việc phân tích cú pháp đều dùng Stack

Những ví dụ gồm có:

Đối sánh các tag trong XHTML


Đối sánh các dấu ngoặc

đơn ( )

vuông, và [ ]

kép { }
trong C++

XHTML sử dụng các tag lồng nhau

Tags mở,ví dụ , <some_identifier>,
đối sánh

tags đóng, ví dụ, </some_identifier>
Ví dụ
<html>
<head><title>Hello</title></head>
<body><p>This appears in the
<i>browswer</i>.</p></body>
</html>
Phân tích cú pháp trong XHTML
Phân tích cú pháp trong
XHTML

Nesting chỉ ra rằng bất kỳ tag đóng nào cũng phải
đối sánh với tag mở gần nhất

Chiến lược phân tích trong XHTML:


Đọc trang tài liệu một cách tuyến tính.

Đặt tag mở vào stack

Khi gặp một tag đóng, kiểm tra nó có đối sánh
với tag đang ở đỉnh stack ?
Phân tích cú pháp trong
XHTML
<html>
<head><title>Hello</title></h
ead>
<body><p>This appears in the
<i>browswer</i>.</p></body>
</html>
<html>
Phân tích cú pháp trong
XHTML
<html>
<head><title>Hello</title></h
ead>
<body><p>This appears in the
<i>browswer</i>.</p></body>
</html>
<html> <head>
Phân tích cú pháp trong
XHTML
<html>
<head><title>Hello</title></h
ead>
<body><p>This appears in the

<i>browswer</i>.</p></body>
</html>
<html> <head> <title>

×