Khái niệm queue Queue Hàng đợi Là một hàng chờ đợi, xếp hàng waiting line Là một cấu trúc dữ liệu trong đó cho phép sử dụng cả 2 phía: một phía để thêm và một phía để lấy ra phần
Trang 1Chương 7
Bài 3 Queue
ĐỖ BÁ LÂM
ViỆN CNTT&TT, TRƯỜNG ĐHBK HÀ NỘI
Nội dung
1 Khái niệm queue
2 Xây dựng queue
2.1 Sử dụng mảng
2.2 Sử dụng danh sách liên kết
2
1 Khái niệm queue
Queue (Hàng đợi)
Là một hàng chờ đợi, xếp hàng (waiting line)
Là một cấu trúc dữ liệu trong đó cho phép sử
dụng cả 2 phía: một phía để thêm và một phía để
lấy ra phần tử
Trang 2lối sau
lối trước
1 Khái niệm Queue
Dữ liệu được thêm vào ở lối sau
(rear), và lấy ra ở lối trước
(front)
Cấu trúc FIFO (First In First Out)
– Vào trước ra trước
Thao tác
enqueue(Element e)
Element dequeue()
Các thao tác cơ bản của Queue
enQueue: Thêm một phần tử vào Queue
Queue
Enqueue D
Data
front rear
Queue
Các thao tác cơ bản của Queue
deQueue: Lấy một phần tử khỏi Queue
Queue
Dequeue
A
Data
front rear
Queue
Trang 3Ứng dụng của Queue
Hàng đợi trong các phòng bán vé
Truy nhập vào các thiết bị dùng chung tại
văn phòng (ví dụ máy in)
7
Ghi nhớ
Queue được hình dung như một hàng đợi
bao gồm nhiều nhiều người xếp hàng với 2
thao tác đưa vào và đẩy ra theo nguyên
tắc:
Người nào vào trước sẽ được ra trước –
FIFO (First In First Out)
2 Xây dựng Queue
Lưu trữ được các đối tượng dữ liệu
Xây dựng 2 thao tác Push và Pop theo
nguyên tắc FIFO
Có hai cách cài đặt queue
Sử dụng mảng
Sử dụng danh sách liên kết
Trang 42.1 Sử dụng mảng
Biễu diễn Queue dưới dạng mảng Q
Lưu trữ chỉ số phần tử lối trước và lối sau
của Queue qua biến F và R
Khởi tạo F=R=-1
Queue rỗng (empty) F = R = -1
Queue đầy (full) R=MAX-1
F (Front) R (Rear)
2.1 Sử dụng mảng
Để thuận tiện định nghĩa cấu trúc Queue
gồm mảng và 2 biến Front, Rear
#define MAX 100
typedef ElementType;
typedef struct {
ElementType Elements[MaxLength];
//Lưu trữ các chỉ số
int Front, Rear;
} Queue;
Queue Q;
11
2.1 Sử dụng mảng
Khởi tạo Queue
Front = -1
Rear = -1
Khi bổ sung thêm một phần tử vào Queue
Nếu Front=-1 thì gán Front=0
Rear tăng lên 1
Khi lấy ra một phần tử trong Queue
Trang 5int EnQueue(ElementType N){
if(Q.Rear==MAX-1)
return 0;
else{
if(Q.Front==-1) Q.Front=0;
Q.Rear=Q.Rear+1;
Q.Elements[Q.Rear]=X;
return 1;
}
Dequeue
int DeQueue(ElementType *N){
if(Q.Front == -1) return 0;
else{
*N = Q.Element[Q.Front];
if (Q.Front == Q.Rear){
Q.Front = -1; Q.Rear = -1;
}else
Q.Front=Q.Front+1;
return 1; //Dequeue thanh cong
} }
2.1 Sử dụng mảng
Nhược điểm của cách tổ chức lưu trữ này
còn chỗ nhưng R = MAX-1
F (Front) R (Rear)
Trang 6EMPTY QUEUE
[1] [2] [1] [2]
[0] [3] [0] [3]
[5] [4] [5] [4]
front = -1 front = 0
rear = -1 rear = 2
J2 J1 J3
Cải tiến
[1] [2] [1] [2]
[0] [3][0] [3]
[5] [4] [5] [4]
J2 J3
J1 J4
J5 J6 J5
J7 J8 J9
Cải tiến
Thêm vào theo chiều kim đồng hồ
front =0
rear = 4
front =4 rear = 2
2.2 Sử dụng danh sách liên kết
Biểu diễn
Front trỏ tới đầu danh sách
Rear: trỏ tới cuối danh sách
Queue là cấu trúc FIFO (First In First Out)
Rear Front
Trang 72.2 Sử dụng danh sách liên kết
Push
Thêm một nút vào sau nút cuối cùng trong
danh sách
Pop
Lấy giá trị nút đầu tiên trong danh sách
Loại bỏ nút này khỏi danh sách
19
2.2 Sử dụng danh sách liên kết
struct node { ElemType data;
struct node *next;
};
struct node *Front, *Rear;
//Front, Rear được khai báo
là hai biến toàn cục
7
1
8
\
Front
Rear
void enQueue(ElemType N){
struct node *Temp;
Temp=(struct node *) malloc(sizeof(struct node));
Temp->data = N;
Temp->next = NULL;
if(Front==NULL){
Front = Temp; Rear = Temp;
}else{
enQueue
7
1
8
\
Front
45
Temp
Rear
Trang 8void enQueue(ElemType N){
struct node *Temp;
Temp=(struct node *) malloc(sizeof(struct node));
Temp->data = N;
Temp->next = NULL;
if(Front==NULL){
Front = Temp; Rear = Temp;
}else{
Rear->next = Temp;
Rear = Rear->next;
}}
enQueue
7
1
8
Front
45
Temp
Rear
void enQueue(ElemType N){
struct node *Temp;
Temp=(struct node *) malloc(sizeof(struct node));
Temp->data = N;
Temp->next = NULL;
if(Front==NULL){
Front = Temp; Rear = Temp;
}else{
Rear->next = Temp;
Rear = Rear->next;
}}
enQueue
7
1
8
Front
45
Temp
Rear
int deQueue(ElementType *N){
struct node *Temp=Front;
if(Front==NULL) return 0;
else{
*N = Front->data;
if(Front==Rear){
Front = NULL;Rear = NULL;
}else
deQueue
7
1
8
Front Temp
Trang 9int deQueue(ElementType *N){
struct node *Temp=Front;
if(Front==NULL) return 0;
else{
*N = Front->data;
if(Front==Rear){
Front = NULL;Rear = NULL;
}else Front = Front->next;
free(Temp);
return 1; } }
deQueue
7
1
8
Front
45
Rear
Temp
int deQueue(ElementType *N){
struct node *Temp=Front;
if(Front==NULL) return 0;
else{
*N = Front->data;
if(Front==Rear){
Front = NULL;Rear = NULL;
}else Front = Front->next;
free(Temp);
return 1; } }
deQueue
1
8
Front
45
Rear
Temp
Bài tập
Demo dQueue.c
Bài 1 Kiểm tra tính đối xứng của một xâu
Dùng stack: lưu các kí tự của xâu
Dùng Queue: lưu các kí tự của xâu
Lấy lần lượt khỏi stack và queue các phần
tử và so sánh
Trang 10Bài tập
Ví dụ
Đầu vào : M A D A M
Bước 1: Đọc xâu từ trái
sang phải, lưu vào trong
Stack và Queue
Bước 2: Lấy lần lượt các
ký tự ra khỏi Stack và
Queue
M A D A M M A D A M
top front
M A D A A D A M
M M
A= A
Bài tập
Bài 2 Kiểm tra cặp ngoặc
Mỗi dấu “(”, “{”, or “[” đều phải có một dấu đóng tương
ứng “)”, “}”, or “[”
Đúng: ( )(( )){([( )])}
Sai: )(( ))
Sai: ({[ ])}
Viết giải thuật nhận một xâu đầu vào gồm các ký
tự mở , đóng ngoặc Kiểm tra xâu có hợp lệ
không
29
Thảo luận