III. HÀNG ĐỢI (QUEUE) 1 Định Nghĩa
b. Cài đặt hàng với mảng xoay vòng
Hình II.12 Cài đặt hàng bằng mảng xoay vòng
Với phương pháp này, khi hàng bị tràn, tức là rear=maxlength-1, nhưng chưa đầy, tức là front>0, thì ta thêm phần tử mới vào vị trí 0 của mảng và cứ tiếp tục như vậy vì từ 0 đến front-1 là các vị trí trống. Vì ta sử dụng mảng một cách xoay vòng như vậy nên phương pháp này gọi là phương pháp dùng mảng xoay vòng.
Các phần khai báo cấu trúc dữ liệu, tạo hàng rỗng, kiểm tra hàng rỗng giống như phương pháp di chuyển tịnh tiến.
Khai báo cần thiết
#define MaxLength ... //chiều dài tối đa của mảng typedef ... ElementType;
//Kiểu dữ liệu của các phần tử trong hàng typedef struct {
ElementType Elements[MaxLength];
//Lưu trữ nội dung các phần tử
} Queue;
Tạo hàng rỗng
Lúc này front và rear không trỏđến vị trí hợp lệ nào trong mảng vậy ta có thể cho front và rear đều bằng -1. void MakeNull_Queue(Queue *Q){ Q->Front=-1; Q->Rear=-1; } Kiểm tra hàng rỗng int Empty_Queue(Queue Q){ return Q.Front==-1; } Kiểm tra hàng đầy
Hàng đầy nếu toàn bộ các ô trong mảng đang chứa các phần tử của hàng. Với phương pháp này thì front có thể lớn hơn rear. Ta có hai trường hợp hàng đầy như sau:
- Trường hợp Q.Rear=Maxlength-1 và Q.Front =0 - Trường hợp Q.Front =Q.Rear+1.
Đểđơn giản ta có thể gom cả hai trường hợp trên lại theo một công thức như sau: (Q.rear-Q.front +1) mod Maxlength =0
int Full_Queue(Queue Q){
return (Q.Rear-Q.Front+1) % MaxLength==0; }
Xóa một phần tử ra khỏi ngăn xếp
Khi xóa một phần tử ra khỏi hàng, ta xóa tại vị trí đầu hàng và có thể xảy ra các trường hợp sau:
Nếu hàng rỗng thì báo lỗi không xóa;
Ngược lại, thay đổi giá trị của Q.Front.
(Nếu Q.front != Maxlength-1 thì đặt lại Q.front = q.Front +1; Ngược lại Q.front=0)
void DeQueue(Queue *Q){
if (!Empty_Queue(*Q)){
//Nếu hàng chỉ chứa một phần tử thì khởi tạo hàng lại if (Q->Front==Q->Rear) MakeNull_Queue(Q);
else Q->Front=(Q->Front+1) % MaxLength; //tăng Front lên 1 đơn vị
}
else printf("Loi: Hang rong!"); }
Thêm một phần tử vào hàng
Khi thêm một phần tử vào hàng thì có thể xảy ra các trường hợp sau: - Trường hợp hàng đầy thì báo lỗi và không thêm;
- Ngược lại, thay đổi giá trị của Q.rear (Nếu Q.rear =maxlength-1 thì đặt lại Q.rear=0; Ngược lại Q.rear =Q.rear+1) và đặt nội dung vào vị trí Q.rear mới.
void EnQueue(ElementType X,Queue *Q){
if (!Full_Queue(*Q)){
if (Empty_Queue(*Q)) Q->Front=0; Q->Rear=(Q->Rear+1) % MaxLength; Q->Elements[Q->Rear]=X;
}
else printf("Loi: Hang day!"); }
Cài đặt hàng bằng mảng vòng có ưu điểm gì so với bằng mảng theo phương pháp tịnh tiến? Trong ngôn ngữ lập trình có kiểu dữ liệu mảng vòng không?