Tải bản đầy đủ (.ppt) (33 trang)

Tài liệu Hàng đợi, sử dụng mảng doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (554.37 KB, 33 trang )


Hàng đợi

Cấu trúc dữ liệu hoạt động theo cơ chế first-in
first-out (FIFO)

Hai thao tác cơ bản:

Chèn vào hàng đợi: enqueue

Lấy ra khỏi hàng đợi: dequeue

Các đối tượng trong hàng đợi được sắp thứ tự
theo thời gian chúng được chèn vào hàng

Đối tượng được lấy ra khỏi hàng đợi là đối
tượng được chèn vào trước nhất

Hàng đợi
A B C D M N
head of queue tail of queue
enqueuedequeue

Hàng đợi, sử dụng mảng
Khai báo cấu trúc hàng đợi
Typerdef struct Queue
{
int *arrQueue;
int max;
int numItems;
int front;


int rear;
}

Hàng đợi, sử dụng mảng

Thao tác khởi tạo hàng đợi rỗng
int InitQueue(Queue &q, int maxItems)
{
q.arrQueue = new int(maxItems);
if(q.arrQueue == Null)
return 0; // không cấp phát được bộ nhớ
q.max = maxItems;
q.numItems = 0; // chưa có phần tử nào trong queue
q.front = q.rear = -1;
return 1; // khởi tạo thành công
}

Hàng đợi, sử dụng mảng

Thao tác kiểm tra hàng đợi rỗng
int IsEmpty(const Queue q)
{
if(q.numItems == 0)
return 1; // Queue rỗng
return 0; // Queue không rỗng
}

Hàng đợi, sử dụng mảng

Thao tác kiểm tra hàng đợi đầy

int IsFull(const Queue q)
{
if(q. numItems == q.max)
return 1; // Queue đầy
return 0; // Queue không đầy
}

Problem

Nếu mảng có kích thước là n, ta có:

Phải thực hiện 11 lần chèn vào, 9 lần lấy ra:
0
0 1
1
1 2
8 9
9
9
enqueue( 0 )
enqueue( 1 )
dequeue()
enqueue( 2 )
enqueue( 9 )
dequeue(8)
enqueue( 10 )

Trừu tượng mảng

Trừu tượng mảng


Giải pháp

Trở lại đầu dãy:

Yêu cầu:

front chỉ số đầu hàng đợi

rear chỉ số cuối hàng đợi

numItems biến đếm

array_size chiều dài mảng
10 9
enqueue( 10 )

Hàng đợi, sử dụng mảng

Thao tác EnQueue: thêm 1 phần tử vào cuối hàng đợi
int EnQueue(Queue &q, int newItem)
{
if (IsFull(q)) return 0; // Queue đầy, không thêm vào được
q.rear++;
if(q.rear == q.max) // tràn giá
q.rear = 0; // quay trở về đầu mảng
q.arrQueue[q.rear] = newItem; // thêm phần tử vào cuối Queue
if(q.numItems == 0) q.front = 0;
q.numItems++;
return 1; // thêm thành công

}

Hàng đợi, sử dụng mảng

Thao tác DeQueue: lấy ra 1 phần tử ở đầu hàng đợi
int DeQueue(Queue &q, int &itemout)
{
if (IsEmpty(q)) return 0; // Queue rỗng, không lấy ra được
itemout = q.arrQueue[q.front]; // lấy phần tử đầu ra
q.front++;
q.numItems ;
if(q.front == q.max) // nếu đi hết mảng …
q.front = 0; // … quay trở về đầu mảng
if(q.numItems == 0) q.front = q.rear = -1;
return 1; // xóa thành công
}

Hàng đợi, sử dụng mảng

Thao tác QueueFront: kiểm tra phần tử ở đầu hàng
đợi
int QueueFront(const Queue &q, int &itemout)
{
if (IsEmpty(q))
return 0;
// lấy phần tử đầu ra
itemout = q.arrQueue[q.front];
return 1;
}


Hàng đợi, sử dụng mảng

Thao tác QueueRear: kiểm tra phần tử ở cuối hàng
đợi
int QueueRear(const Queue &q, int &itemout)
{
if (IsEmpty(q))
return 0;
// lấy phần tử cuối ra
itemout = q.arrQueue[q.rear];
return 1;
}

Applications

Kiểu Client-server :

Một hoặc nhiều clients đang yêu cầu được phục vụ từ
một hay nhiều servers

Có thể có nhiều hơn một client đang đợi để được
phục vụ tại cùng thời điểm

Các clients trong hàng đợi sẽ được phục vụ theo theo
thứ tự thời gian chúng được chèn vào

Application

Một vài ứng dụng dễ nhìn thấy:


Kiểu client-server, khi mà có nhiều hơn một client gởi
yêu cầu phục vụ tới một Web server

Ví dụ, một (simple) web server chỉ có thể phục vụ mỗi
lần một yêu cầu

Rõ ràng có nhiều yêu cầu hầu như đồng thời được
gởi tới từ các trình duyệt

Yêu cầu đầu tiên sẽ được phục vụ, những yêu cầu
tiếp theo được đưa vào hàng đợi

Application

Một ứng dụng khác là thực hiện duyệt một cây
theo chiều ngang (breadth-first)

Cho trước một cây sau

Application

Giả sử ta muốn liệt kê tất cả nút theo trật tự
breadth-first

Ta liệt kê tất cả nút ở một mức trước khi xuống
mức tiếp theo

Application

Về điều này, ta cần một vài thuật ngữ:


Nút gốc (root node)

Nút con (child nodes hoặc children)

Application

Việc hiện thực dễ nhất là:

Đặt nút gốc vào hàng đợi

Khi hàng đợi không rỗng:

Lấy nút head ra

chèn tất cả con của nó vào hàng đợi

Trật tự của các phần tử được lấy ra khỏi hàng đợi gọi
là trật tự breadth-first

Application

Đưa nút gốc A vào

Application

Lấy A ra và đưa hai con của nó là B và H vào

Application


Lấy B ra và chèn C, D, và G

Application

Lấy H ra và đưa I là con của nó vào

Application

Lấy C ra – C không có con

×