Hàng ñợi (Queue)

Một phần của tài liệu Cấu Trúc Dữ Liệu và Giải Thuật - chương 3 pdf (Trang 63 - 80)

- Tốn chi phí tái cấp phát và sao chép vùng nhớ nếu sử dụng

3.5.2. Hàng ñợi (Queue)

Hàng ñợi là một vật chứa (container) các ñối tượng

Làm việc theo cơ chế FIFO (First In First Out) "Vào trước ra trước".

Phòng vé

CTDL Queue hỗ trợ các thao tác:

InitQueue: Khởi tạo hàng ñợi rỗng

IsEmpty: Kiểm tra hàng ñợi rỗng ?

IsFull: Kiểm tra hàng ñợi ñầy ?

EnQueue: Thêm 1 phần tử vào cuối hàng ñợi, có thể làm hàng ñợi ñầy

DeQueue: Lấy ra 1 phần tử từ ñầu Queue, có thể làm Queue rỗng

QueueFront: Kiểm tra phần tử ñầu Queue

65

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương Ðể biểu diễn Queue: Dùng mảng 1 chiều hoặc danh sách liên kết.

Mảng 1 chiều Danh sách liên kết ñơn

- Viết chương trình dễ dàng, nhanh chóng nhanh chóng

- Bị hạn chế do số lượng phần tửcố ñịnh cố ñịnh

- Tốn chi phí tái cấp phát và saochép vùng nhớ nếu sử dụng chép vùng nhớ nếu sử dụng

mảng ñộng

Phức tạp khi triển khai chương trình

Không bị cố ñịnh về số phần tử, phụ thuộc vào bộ nhớ

Mảng (QArray) ñể chứa các phần tử.

Số nguyên (QMax)ñể lưu số phần tử tối ña

2 số nguyên (Qfront/QRear) ñể xác ñịnh vị trí ñầu/cuối

Số nguyên (QNumItems) ñể lưu số phần tử hiện có

Hàng ñợi sử dụng mảng 0 1 2 3 4 5 6 Qarray 37 22 15 3 QMax = 7 QNumItems = 4 QFront = 1 QRear = 4

67

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

// Giả sử Queue chứa các phần tử kiểu nguyên (int) // Khai báo cấu trúc Queue

typedef struct QUEUE { int* QArray; int QMax; int QNumItems; int QFront; int QRear; };

Khi thêm nhiều phần tử sẽ xảy ra hiện tượng “tràn giả”

Giải pháp? Nối dài mảng (mảng ñộng) hay sử dụng một mảng vô cùng lớn? 0 1 2 3 4 5 6 Qarray 37 22 15 3 7 9 QMax = 7 QNumItems = 4 QFront = 1 QRear = 7

69

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

//Thao tác “Khởi tạo Queue rỗng”:

int InitQueue(QUEUE& q, int MaxItem) {

q.QArray = new int[MaxItem]; if (q.QArray == NULL) return 0; // không ñủ bộ nhớ q.QMax = MaxItem; q.QNumItems = 0; q.QFront = q.QRear = -1; return 1; // thành công }

//Thao tác “Kiểm tra Queue rỗng”: int IsEmpty(QUEUE q) { if (q.QNumItems == 0) return 1; // rỗng return 0; // không rỗng }

//Thao tác “Kiểm tra Queue ñầy”:

int IsFull(QUEUE q) {

if (q.QMax == q.QNumItems) return 1; // ñầy

71

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

//Thao tác EnQueue: thêm 1 phần tử vào cuối Queue

int EnQueue(QUEUE &q, int newitem) {

if (IsFull(q))

return 0; // Queue ñầy, không thêm vào ñược

q.QRear++;

if (q.QRear==q.QMax) // “tràn giả”

q.QRear = 0; // Quay trở về ñầu mảng

q.QArray[q.QRear] = newitem;

// thêm phần tử vào cuối Queue

if (q.QNumItems==0) q.QFront = 0; q.QNumItems++;

return 1; // Thêm thành công

//Thao tác DeQueue: lấy ra 1 phần tử ở ñầu Queue

int DeQueue(QUEUE &q, int& itemout) {

if (IsEmpty(q))

return 0; // Queue rỗng, không lấy ra ñược

itemout = q.QArray[q.QFront]; // lấy phần tử ñầu ra

q.QFront++;

q.QNumItems--;

if (q.QFront==q.QMax) // nếu ñi hết mảng …

q.QFront = 0; // … quay trở về ñầu mảng

if (q.QNumItems==0) // nếu lấy ra phần tử cuối cùng

q.QFront = q.QRear = -1; // khởi tạo lại Queue

return 1; // Lấy ra thành công

73

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

//Thao tác QueueFront: Kiểm tra phần tử ở ñầu Queue

int QueueFront(const QUEUE &q, int& itemout) {

if (IsEmpty(q))

return 0; // Queue rỗng, không kiểm tra

// lấy phần tử ñầu ra

itemout = q.QArray[q.QFront]; return 1;

}

//Thao tác QueueRear: Kiểm tra phần tử ở cuối Queue

int QueueRear(const QUEUE &q, int& itemout) {

if (IsEmpty(q))

return 0; // Queue rỗng, không kiểm tra

// lấy phần tử cuối ra

itemout = q.QArray[q.QRear]; return 1;

//Khai báo cấu trúc

typedef struct tagNODE {

int data;

tagNODE* pNext; } NODE, *PNODE;

typedef struct tagQUEUE {

int NumItems;

PNODE pFront, pRear; } QUEUE;

75

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

Các thao tác cơ bản

int InitQueue(QUEUE& q);

int IsEmpty(const QUEUE& q);

int IsFull(const QUEUE& q);

int EnQueue(QUEUE &q, int newitem);

int DeQueue(QUEUE &q, int& itemout);

int QueueFront(const QUEUE &q, int& itemout);

//Khởi tạo Queue rỗng

int InitQueue(QUEUE& q) {

q.NumItems = 0;

q.pFront = q.pRear = NULL; return 1;

77

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

//Kiểm tra Queue rỗng

int IsEmpty(const QUEUE& q) {

return (q.NumItems==0); }

//Kiểm tra Queue ñầy

int IsFull(const QUEUE& q) {

PNODE tmp = new NODE; if (tmp==NULL)

return 1; delete tmp; return 0; }

//Thêm 1 phần tử vào cuối Queue

int EnQueue(QUEUE &q, int newitem) {

if (IsFull(q)==1) return 0;

PNODE p = new NODE; p->data = newitem;

p->pNext = NULL;

if (q.pFront==NULL && q.pRear==NULL) q.pFront = q.pRear = p; else { q.pRear->pNext = p; q.pRear = p; }

79

© Dương Thành Phết-www.thayphet.net Khoa KTCN Trường ðH KTKT B.Dương

//Lấy ra 1 phần tử ở ñầu Queue

int DeQueue(QUEUE &q, int& itemout) { if (IsEmpty(q)==1) return 0; PNODE p = q.pFront; q.pFront = p->pNext; itemout = p->data; q.NumItems--; delete p; if (q.NumItems==0) InitQueue(q); return 1; }

//Kiểm tra 1 phần tử ở ñầu Queue

int QueueFront(const QUEUE &q, int& itemout) { if (IsEmpty(q)==1) return 0; itemout = q.pFront->data; return 1; }

//Kiểm tra 1 phần tử ở cuối Queue

int QueueRear(const QUEUE &q, int& itemout) {

if (IsEmpty(q)==1) return 0;

itemout = q.pRear->data; return 1;

Một phần của tài liệu Cấu Trúc Dữ Liệu và Giải Thuật - chương 3 pdf (Trang 63 - 80)

Tải bản đầy đủ (PDF)

(80 trang)