Mọi vấn đề của thực tế liên quan tới cơ chế FIFO như cơ chế gửi tiền, rút tiền trong ngân hàng, đặt vé máy bay đều có thể ứng dụng được bằng hàng đợi. Hàng đợi còn có những ứng dụng trong việc giải quyết các bài toán của Hệđiều hành và chương trình dịch như bài toán điều khiển các quá trình, điều khiển nạp chương trình vào bộ nhớ hay bài toán lập lịch. Bạn đọc có thể tham khảo thêm trong các tài liệu [1], [2]. Dưới đây, chúng ta đưa ra một ứng dụng của hàng đợi để giải quyết bài toán “Nhà sản xuất và Người tiêu dùng”.
Ví dụ 3.2- Giải quyết bài toán ”Người sản xuất và nhà tiêu dùng “ với số các vùng đệm hạn chế.
Chúng ta mô tả quá trình sản xuất và tiêu dùng như hai quá trình riêng biệt và thực hiện song hành, người sản xuất có thể sản xuất tối đa n mặt hàng. Người tiêu dùng chỉđược phép sử dụng trong sốn mặt hàng. Tuy nhiên, người sản xuất chỉ có thể lưu trữ vào kho khi và chỉ khi kho chưa bịđầy. Ngược lại, nếu kho hàng không rỗng (kho có hàng) người tiêu dùng có thể tiêu dùng những mặt hàng trong kho theo nguyên tắc hàng nào nhập vào kho trước được tiêu dùng trước giống như cơ chế FIFO của queue. Sau đây là những thao tác chủ yếu trên hàng đợi để giải quyết bài toán:
Ta xây dựng hàng đợi như một danh sách tuyến tính gồm MAX phần tử mỗi phần tử
là một cấu trúc, hai biến front, rear trỏđến lối vào và lối ra trong queue:
typedef struct{ int mahang; char ten[20]; } hang;
typedef struct {
int front, rear; hang node[MAX]; } queue;
Thao tác Initialize: thiết lập trạng thái ban đầu của hàng đợi. Ở trạng thái này, font và rear có cùng một giá trị MAX-1.
void Initialize ( queue *pq){
pq->front = pq->rear = MAX -1; }
Thao tác Empty: kiểm tra hàng đợi có ở trạng thái rỗng hay không. Hàng đợi rỗng khi front == rear.
int Empty(queue *pq){
if (pq->front==pq->rear) return(TRUE); return(FALSE); }
Thao tác Insert: thêm X vào hàng đợi Q. Nếu việc thêm X vào hàng đợi được thực hiện ởđầu hàng, khi đó rear có giá trị 0, nếu rear không phải ởđầu hàng đợi thì giá trị của nó được tăng lên 1 đơn vị.
void Insert(queue *pq, hang x){ if (pq->rear==MAX-1 ) pq->rear=0; else
(pq->rear)++; if (pq->rear ==pq->front){
printf("\n Queue full"); delay(2000);return; }
else
pq->node[pq->rear]=x; }
Thao tác Remove: loại bỏ phần tửở vị trí front khỏi hàng đợi. Nếu hàng đợi ở trạng thái rỗng thì thao tác Remove không thể thực hiện được, trong trường hợp khác front được tăng lên một đơn vị.
hang Remove(queue *pq){ if (Empty(pq)){
printf("\n Queue Empty"); delay(2000); } else { if (pq->front ==MAX-1) pq->front=0; else pq->front++; } return(pq->node[pq->front]); }
Thao tác Traver: Duyệt tất cả các nút trong hàng đợi.
void Traver( queue *pq){ int i;
if(Empty(pq)){
printf("\n Queue Empty");
return;
}
if (pq->front ==MAX-1)
else
i = pq->front+1; while (i!=pq->rear){
printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); if(i==MAX-1)
i=0;
else
i++; }
printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); }
Dưới đây là toàn bộ văn bản chương trình:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <dos.h> #include <string.h> #include <math.h> #define MAX 50 #define TRUE 1 #define FALSE 0 typedef struct{ int mahang; char ten[20]; } hang; typedef struct {
int front, rear; hang node[MAX]; } queue;
/* nguyen mau cua ham*/ void Initialize( queue *pq); int Empty(queue *); void Insert(queue *, hang x); hang Remove(queue *);
void Traver(queue *); /* Mo ta ham */
void Initialize ( queue *pq){
pq->front = pq->rear = MAX -1; }
int Empty(queue *pq){
return(TRUE); return(FALSE); }
void Insert(queue *pq, hang x){ if (pq->rear==MAX-1 ) pq->rear=0; else
(pq->rear)++; if (pq->rear ==pq->front){
printf("\n Queue full"); delay(2000);return; } else pq->node[pq->rear]=x; } hang Remove(queue *pq){ if (Empty(pq)){
printf("\n Queue Empty"); delay(2000); } else { if (pq->front ==MAX-1) pq->front=0; else pq->front++; } return(pq->node[pq->front]); }
void Traver( queue *pq){ int i;
if(Empty(pq)){
printf("\n Queue Empty");
return; } if (pq->front ==MAX-1) i=0; else i = pq->front+1; while (i!=pq->rear){
printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); if(i==MAX-1)
i=0;
else
i++; }
printf("\n %11d % 15s", pq->node[i].mahang, pq->node[i].ten); }
void main(void){ queue q;
char chucnang, front1; char c; hang mh; clrscr();
Initialize(&q); do {
clrscr();
printf("\n NGUOI SAN XUAT/ NHA TIEU DUNG"); printf("\n 1- Nhap mot mat hang");
printf("\n 2- Xuat mot mat hang"); printf("\n 3- Xem mot mat hang"); printf("\n 4- Xem hang moi nhap"); printf("\n 5- Xem tat ca");
printf("\n 6- Xuat toan bo");
printf("\n Chuc nang chon:");chucnang=getch(); switch(chucnang){
case ‘1’:
printf("\n Ma mat hang:"); scanf("%d", &mh.mahang); printf("\n Ten hang:");scanf("%s", mh.ten);
Insert(&q,mh);break;
case ‘2’:
if (!Empty(&q)){
mh=Remove(&q);
printf("\n %5d %20s",mh.mahang, mh.ten); }
else {
printf("\n Queue Empty"); delay(1000);
}
break;
case ‘3’:
front1=(q.front==MAX-1)?0:q.front+1; printf("\n Hang xuat");
printf("\n%6d%20s",q.node[front1].mahang,q.node[front1].ten); break;
case ‘4’:
printf("\n Hang moi nhap");
printf("\n%5d%20s",q.node[q.rear].mahang,q.node[q.rear].ten); break;
case ‘5’:
printf("\ Hang trong kho"); Traverse(&q);delay(2000);break;
}
} while(chucnang!=’0’); }