Bài giảng Cấu trúc dữ liệu và Giải thuật - Ngăn xếp và Hàng Đợi - Phạm Ngọc Nam
1. Stack (Ngăn xếp) Giới thiệu Các thao tác cơ bản Các ứng dụng 2. Queue (Hàng Đợi) Giới thiệu Các thao tác cơ bản Ứng dụng
Bạn đang xem trước 20 trang tài liệu Bài giảng Cấu trúc dữ liệu và Giải thuật - Ngăn xếp và Hàng Đợi - Phạm Ngọc Nam, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Cấu Trúc Dữ Liệu & Giải Thuật
Stack and Queue
GV : Phạm Ngọc Nam
Khoa : CNTT
Email: [email protected]
2Stack (Ngăn xếp) 
Giới thiệu
Các thao tác cơ bản
Các ứng dụng
3Queue (Hàng Đợi) 
Giới thiệu
Các thao tác cơ bản
Ứng dụng
4 Một chồng Sách Vở ở trên bàn
 Một chồng Đĩa
 Nhận xét gì từ các ví dụ trên?
Giới thiệu
Một số hình ảnh thông dụng
5 Ngăn xếp là cấu trúc chứa 
các đối tượng làm việc theo cơ 
chế “ vào sau ra trước” (Last in 
First out).
 đối tượng có thể được thêm 
vào bất kỳ lúc nào, nhưng chỉ có 
đối tượng vào sau cùng mới 
được phép lây ra khỏi ngăn xếp.
Giới thiệu
Định nghĩa:
6 Lưu trữ Ngăn Xếp.
 khởi tạo Stack rỗng
 Kiểm tra Ngăn Xếp rỗng.
 Thêm một phần tử vào Ngăn Xếp.
 Lấy một phần tử ra khỏi Ngăn Xếp.
 Lấy thông tin của phần tử đầu Ngăn Xếp.
Các thao tác trên ngăn xếp
7 Thêm vào đầu danh sách(AddHead):
phần tử mới thêm nằm ở đầu danh sách
 Truy xuất danh sách: Truy xuất phần tử nằm 
ở đầu trước.
=> Thích hợp với tính chất của Ngăn Xếp.
Lưu trữ Stack bằng DSLK
8Lưu trữ Stack bằng DSLK
9 Cài đặt
 khai báo cấu trúc 1 phần tử trong Stack
struct NodeStack{
dataType data;
NodeStack *pNext;
};
 khai báo cấu trúc Stack
struct Stack{
int count;
NodeStack *pHead;
};
Lưu trữ Stack bằng DSLK
10
 Cài đặt:
void InitStack(Stack &s)
{
s.count = 0;
s.pHead==NULL)
}
Khởi tạo Stack 
11
 Ngăn xếp rỗng khi không chứa phần tử nào.
 Cài đặt:
bool IsEmpty(const Stack s)
{
if(s.pHead==NULL)
return true;
return false;
}
Kiểm tra Stack Rỗng
12
 Ngăn xếp đầy khi không thể cấp phát thêm vùng 
nhớ.
 Khi thêm 1 phần tử vào Ngăn Xếp, nếu không cấp 
phát được vùng nhớ => Thông báo ngăn xếp đầy.
Kiểm tra Stack đầy
bool IsFull(const Stack &s)
{
NodeStack *pNew=new NodeStack;
if(pNew == NULL)// nếu ko tạo đc stack đầy
return true;
return false;// stack ko đầy
}
13
 Giải Thuật:
 Tương tự thao tác thêm đầu(AddHead).
 Nếu không thêm được(do không cấp phát 
được vùng nhớ) trả về giá trị cho biết ngăn 
xếp đầy.
 Cài đặt:
Thêm một phần tử
14
 Cài đặt:
int Push(Stack &s, int x)
{
NodeStack *pNew = new NodeStack;
if(pNew == NULL)
return 0;// ko cấp phát được 
vùng nhớ, stack đầy
pNew -> data = x;
pNew -> pNext = NULL;
if(s.pHead == NULL){
s.pHead = pNew;
return 1;
}
else{
pNew -> pNext = s.pHead;
s.pHead = pNew;
return 1;
}
}
Thêm một phần tử
15
 Cài đặt cách khác
int Push(Stack &s, int x)
{
if(IsFull(s))
return 0;// stack đầy ko thêm đc
NodeStack *pNew = new NodeStack;
pNew -> data = x;
pNew -> pNext = s.pHead;
s.pHead = pNew;
s.count ++;
return 1; // thêm thành công
}
Thêm một phần tử
16
 Lấy đối tượng ở đầu Ngăn Xếp ra khỏi Ngăn Xếp và trả về 
giá trị của đối tượng đó.
 Nếu Stack rỗng báo lỗi.
 Thuật toán:
 kiểm tra Ngăn Xếp rỗng hay không
 Nếu không:
 Ghi nhận giá trị của phần tử ở đầu Ngăn Xếp.
 Xóa phần tử đầu ra khỏi Ngăn Xếp.
 Trả về giá trị đã ghi nhận.
Lấy một phần tử ra khỏi ngăn xếp
17
 Cài đặt
DataType * Pop(Stack &s)
{
// Kiểm tra Ngăn Xếp rỗng
if(.)
return 0;
// Ghi nhận giá trị đầu Ngăn Xếp
datatype x= l.pHead->data;
// Xóa đầu Ngăn Xếp
/ / Trả về giá trị đã ghi nhân
return ;
}
Lấy một phần tử ra khỏi ngăn xếp
18
 Cài đặt
int Pop(Stack &s)
{
if(s.pHead = = NULL)
return 0; // stack rỗng không lấy ra được
NodeStack * pNew = s.pHead;
s.pHead = pNew ->pNext;
delete pNew ;
s.count --;
return 1; // xóa thành công
}
Lấy một phần tử ra khỏi ngăn xếp
19
 Cài đặt
int Pop(Stack &s, int &outdata)
{
if(IsEmpty(s))
return 0; // stack rỗng không lấy ra được
NodeStack * pNew = s.pHead;
outdata = pNew -> data;
s.pHead = pNew ->pNext;
delete pNew ;
s.count --;
return 1; // lấy ra thành công
}
Lấy một phần tử ra khỏi ngăn xếp
20
 Lưu vết trong các giải thuật “back-tracking”
 Bài toán “N quân hậu”
Các ứng dựng của Stack
21
Queue (Hàng Đợi) 
21
Giới thiệu
Các thao tác cơ bản
Ứng dụng
22
 Queue là cấu trúc chứa các đối tượng làm
việc theo qui tắc “ Vào sau ra trước(FIFO)”.
 Các đối tượng có thể được thêm vào hàng 
đợi bất kì lúc nào nhưng chỉ có đối tượng thêm 
vào đầu tiên mới được lấy ra khỏi hàng đợi.
 Việc thêm vào diễn ra ở cuối, việc lấy ra diễn 
ra ở đầu.
Giới thiệu
23
 Lưu trữ Queue.
 kiểm tra Queue rỗng
Thêm một phần tử vào cuối Queue.
 Lấy một phần tử ở đầu ra khỏi Queue.
 Lấy thông tin của đối tượng ỏ đầu Queue.
Các thao tác trên Queue
24
 Khai báo hàng đợi như một DSLK với phần 
tử đầu (pHead) và đuôi (pTail).
 Phần tử đầu: nơi lấy dữ liệu hàng đợi ra.
Phần tử đuôi: nơi thêm phần tử vào
Lưu trữ Queue bằng DSLK
25
 Hàng đợi rỗng khi không có phần tử nào 
(DS rỗng)
Kiểm tra Queue rỗng
 Cài đặt
bool IsEmpty(NodeQueue *q)
{
if(q->pHead = = NULL)
return true; 
return false;
}
26
 Hàng đợi đầy khi không thể cấp phát thêm 
vùng nhớ.
Kiểm tra Queue đầy
 Khi thêm 1 phần tử vào hàng đợi, nếu không 
cấp phát được vùng nhớ -> Thông báo hàng đợi 
đầy
 Cài đặt
bool IsFull()
{
if()
}
27
 Giải thuật:
 Tương tự thao tác thêm cuối.
Thêm phần tử vào cuối Queue
 Nếu không thêm được (do không cấp phát 
được vùng nhớ) trả về giá trị cho biết hàng đợi đầy
 Cài đặt:
int EnQueue (NODE *&pHead, NODE *&pTail, Data x) 
{
//tạo 1 nút mới
if()
return 0;
//thêm nút mới vào đuôi
return 1;
}
28
 Giải thuật:
 Ghi nhận giá trị của phần tử ở đầu hàng đợi.
 Xóa phần tử đầu ra khỏi hàng đợi.
 Trả về giá trị đã ghi nhận.
Lấy phần tử đầu ra khỏi Queue
 Cài đặt:
Data DeQueue(NODE*& pHead, NODE*& pTail) 
{
//kiểm tra Queue rỗng?
if()
return ;
////ghi nhận giá trị đầu Queue
Data x = pHead -> data;
//xóa đầu Queue
//trả về giá trị đã ghi nhận
return _______;
}
29
 Giải thuật:
 Chỉ lấy thông tin của đối tượng đầu hàng đợi mà không 
hủy đối tượng khỏi hàng đợi.
Lấy phần tử đầu Queue
 Cài đặt:
 Kiểm tra hàng đợi rỗng?
 Trả về giá trị của phần tử đầu hàng đợi.
Data DeQueue(NODE*& pHead) 
{
.
}
30
 Sử dụng giải 1 số bài toán lý thuyết đồ thị.
Các ứng dựng của Queue
            
         
    




