Tải bản đầy đủ (.pdf) (25 trang)

Stack Cấu Trúc Dữ Liệu Và Giải Thuật Chapter 4.1 Stack

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 (1.15 MB, 25 trang )

Chương 4:
Stack, Queue
1


Phần 1: Ngăn xếp (Stack)

2


Khái niệm Stack
LIFO: Last In First Out
Thao tác Pop, Push chỉ diễn ra ở 1 đầu

3


Biếu diễn stack
Mảng 1 chiều

Danh sách LK
Cấp phát
động!

Kích thước stack
khi quá thiếu, lúc
quá thừa

Push/Pop
khá dễ
dàng



Push / Pop hơi
phức tạp

4


Biểu diễn Stack dùng mảng
 Có thể tạo một stack bằng cách khai báo một mảng 1
chiều với kích thước tối đa là N (ví dụ: N =1000).
 Stack có thể chứa tối đa N phần tử đánh số từ 0 đến
N-1.
 Phần tử nằm ở đầu stack sẽ có chỉ số Top (lúc đó
trong stack đang chứa Top +1 phần tử)
 Để khai báo một stack, ta cần một mảng 1 chiều S,
biến nguyên t cho biết chỉ số của đầu stack và hằng
số N cho biết kích thước tối đa của stack.
Data S [N];
int
Top;
5


Khai báo Stack
typedef struct item
{
int data;
};
typedef struct stack
{

int top;
node Ary[N];
};
6


Các thao tác trên Stack
Các thao tác cơ bản trên stack
 Khởi tạo stack: Init (S)
 Kiểm tra stack rỗng: Empty (S)
 Kiểm tra stack đầy: IsFull (S)
 Đưa phần tử vào Stack: Push(S,x)
 Lấy phần tử ra khỏi Stack: Pop (S, x)

7 179/44


Biểu diễn Stack dùng mảng
 Khởi tạo Stack:
 Lệnh Top = -1 sẽ tạo ra một stack S rỗng.
 Đảm bảo các thao tác trên Stack thực hiện đúng đắn.
Thuật toán:
+Vào: Stack đã cần khởi tạo.
+ Ra: Stack sau khi khởi tao.
B1) Đặt chỉ số top = -1
BKT) Kết thúc;

Cài đặt:
void Init (stack &s)
{

s.top=-1;
}

8


Biểu diễn Stack dùng mảng
Kiểm tra stack rỗng
 Được gọi đến trước khi thực hiện thao tác lấy
phần tử ra khỏi Stack.
 Stack rỗng nếu chỉ số top = -1.
Thuật toán:
+Vào: Stack cần kiểm tra.
+ Ra: Giá trị 0 hoặc 1.
B1) if top=-1 then return 1
else return 0
BKT) Kết thúc.
9

Cài đặt:
int IsEmpty (stack s)
{
if (s.top == -1)
return 1;
return 0;
}


Biểu diễn Stack dùng mảng
Kiểm tra stack đầy

 Được gọi đến trước khi thực hiện thao tác đưa một
phần tử vào stack.
 Stack đầy nếu top = N-1.
Thuật toán:
+Vào: Stack cần kiểm tra.
+ Ra: giá trị 0 hoặc 1
B1) if top = N-1 then return 1;
else return 0;
BKT) Kết thúc;

10

Cài đặt:
int IsFull (stack s)
{
if (s.top==N-1)
return 1;
return 0;
}


Biểu diễn Stack dùng mảng
Thêm một phần tử vào Stack
Thuật toán
 Vào: Stack S, phần tử dữ liệu x
 Ra: Stack với phần tử dữ liệu trên đỉnh Stack.
B1) Kiểm tra nếu stack chưa đầy thì:
B1.1) Tăng top lên 1;
B1.2) Giá trị phần tử trên đỉnh Stack = x;
B1.3) Thực hiện bước kết thúc;

B2) Nếu stack rỗng thì thực hiện BKT;
BKT) Kết thúc;
11


Biểu diễn Stack dùng mảng
Cài đặt:
void Push(stack &s,node x){
if(!Full(s))
{ // stack chưa đầy
s.top++;
s.Ary[s.top]=x;
}
}

12


Biểu diễn Stack dùng mảng
Lấy phần tử ra khỏi Stack
Thuật toán
 Vào: Stack S;
 Ra: x lưu giá trị phần tử trên đỉnh Stack.
B1) Kiểm tra nếu stack không rỗng thì:
B1.1) x = giá trị phần tử trên đỉnh Stack = x;
B1.2) Giảm top đi 1 ;
B1.3) Thực hiện bước kết thúc;
B2) Nếu stack rỗng thì thực hiện BKT;
BKT) Kết thúc;
13



Biểu diễn Stack dùng mảng
Cài đặt:
node Pop(stack &s)
{
item x;
if(!Empty(s)) // stack khác rỗng
{
x = s.Ary[s.top];
s.top--;

}
return x;
}

14


Biểu diễn Stack dùng mảng
Nhận xét:
 Ưu điểm:
• Các thao tác trên đều làm việc với chi phí O(1).
• Việc cài đặt stack thông qua mảng một chiều đơn
giản và khá hiệu quả.

 Hạn chế:
• Giới hạn về kích thước của stack N.
• Giá trị của N có thể quá nhỏ so với nhu cầu thực
tế hoặc quá lớn sẽ làm lãng phí bộ nhớ.


Khắc phục: Sử dụng DSLK đơn để biểu diễn stack
15


Biểu diễn Stack dùng DSLK
Cấu trúc Node
typedef struct Node
{
int data;
node *next;
};

Khai báo Stack
typedef struct stack
{
Node *top;
};
16


Biểu diễn Stack dùng DSLK
Các thao tác cơ bản trên stack
 Khởi tạo stack: Init (S)
 Tạo mới 1 nút: CreateNode (x)
 Kiểm tra stack rỗng: IsEmpty (S)
 Đưa phần tử vào Stack: Push (S,x)
 Lấy phần tử ra khỏi Stack: Pop (S, x)

17 179/44



Biểu diễn Stack dùng DSLK
Khởi tạo stack
 Lệnh top = NULL sẽ tạo ra một stack S rỗng.
Thuật toán:
+Vào: Stack đã cần khởi tạo.
+ Ra: Stack sau khi khởi tao.
B1) Đặt top = NULL;
BKT) Kết thúc;

Cài đặt:
void Init (stack &s)
{
s.top = NULL;
}

18


Biểu diễn Stack dùng DSLK
Kiểm tra stack rỗng
 Stack rỗng nếu top = NULL.
Thuật toán:
+Vào: Stack cần kiểm tra.
+ Ra: Giá trị 0 hoặc 1.
B1) if top = NULL then return 1;
else return 0
BKT) Kết thúc.


19

Cài đặt
int IsEmpty(stack s)
{
if (s.top == NULL)
return 1;
return 0; // stack rỗng
}


Biểu diễn Stack dùng DSLK
 Tạo mới một nút:
Node* CreateNode (int x) {
Node *p;
p = (Node*) malloc (sizeof(Node));
if (p==NULL) {
printf (“Khong du bo nho!”);
return NULL;
}
p->data=x;
p->next=NULL;
return p;
}
20


Biểu diễn Stack dùng mảng
Thêm một phần tử vào Stack
Thuật toán

 Vào: Stack S, phần tử dữ liệu x
 Ra: Stack với phần tử dữ liệu trên đỉnh Stack.
B1) NewNode  Tạo mới một nút chứa dữ liệu x;
B2) Nếu không tạo được nút thì thực hiện BKT;
B3) Kiểm tra nếu danh sách rỗng thì
top = NewNode;
Ngược lại, chèn NewNode vào đầu danh sách.
BKT) Kết thúc;
21


Biểu diễn Stack dùng DSLK
Cài đặt:
void Push (stack &s, int x){
Node *NewNode = CreateNode (x);
if (NewNode != NULL){
if (IsEmpty(s)) s.top = NewNode;
else{
NewNode->next = s.top;
s.top = NewNode;
}
}
}
22


Biểu diễn Stack dùng mảng
Lấy phần tử ra khỏi Stack
Thuật toán
 Vào: Stack S;

 Ra: Phần tử trên đỉnh Stack.
B1) Kiểm tra nếu stack không rỗng thì:
B1.1) p phần tử trên đỉnh Stack;
B1.3) Thực hiện bước kết thúc;
B2) Nếu stack rỗng thì thực hiện BKT;
BKT) Kết thúc;

23


Biểu diễn Stack dùng DSLK
Cài đặt:
int Pop (stack &s){
node *p;
int x;
if (!Empty(s))
{
p = s.top;
s.top = p->next;
x = p->data;
delete p;
return x;
}
}
24


Ứng dụng của Stack
Stack thích hợp lưu trữ các loại dữ liệu mà trình
tự truy xuất ngược với trình tự lưu trữ

Một số ứng dụng của Stack:
 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.
 Lưu dữ liệu khi giải một số bài toán của lý
thuyết đồ thị (như tìm đường đi)
 Khử đệ qui
 ...
25


×