ctdl ktlt tuan5
TRANSCRIPT
HDTH CTDL & KTLT nâng cao tuần 5
1. Queue là gì?
Queue là một cấu trúc dữ liệu:
- Dùng để lưu trữ nhiều phần tử dữ liệu.
- Hoạt động theo cơ chế “Vào trước – ra trước” (First In First Out – LIFO).
2. Các thao tác cơ bản trên Queue
Thao tác cơ bản trên Queue chỉ bao gồm:
- EnQueue: Thêm một phần tử vào cuối Queue, có thể làm Queue đầy.
- DeQueue: Lấy ra một phần tử ở đầu Queue, có thể làm Queue rỗng.
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 1
HDTH CTDL & KTLT nâng cao tuần 5
Ngoài 2 thao tác cơ bản trên, người ta còn xây dựng thêm các thao tác cơ bản khác
dùng để phụ trợ thêm cấu trúc Queue:
- InitQueue: dùng để khởi tạo Queue rỗng.
- IsEmpty: dùng để kiểm tra Queue có rỗng hay không?
- IsFull: dùng để kiểm tra Queue có đầy hay chưa?
- QueueFront: dùng để trả về phần tử đầu Queue mà không loại bỏ phần tử đó ra
khỏi Queue.
- QueueSize: dùng để cho biết số phần tử hiện đang có trong Queue.
3. Xây dựng Queue bằng mảng (chỉ mang tính chất tham
khảo)
3.1. Khai báo cấu trúc Queue bằng struct
// 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; // mảng chứa các phần tử
int Max; // số phần tử tối đa
int NumItems; // số phần tử hiện có
int Front; // vị trí đầu queue
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 2
HDTH CTDL & KTLT nâng cao tuần 5
int Rear; // vị trí cuối queue
};
typedef struct queue QUEUE;
3.2. Các hàm xử lý thao tác
int InitQueue(QUEUE &q, int MaxItems);
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);
3.2.1. Hàm khởi tạo Queue
// khởi tạo Queue rỗng, có tối đa MaxItems phần tử
int InitQueue(QUERE &q, int MaxItems)
{
q.QArray = new int[MaxItems];
if (q.QArray==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
}
3.2.2. Hàm kiểm tra Queue rỗng
// Hàm kiểm tra queue = rỗng ?
int IsEmpty(const QUEUE &q)
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 3
HDTH CTDL & KTLT nâng cao tuần 5
{
if (q.NumItems==0)
return 1; // Queue rỗng
return 0; // Queue không rỗng
}
3.2.3. Hàm kiểm tra Queue đầy
// Hàm kiểm tra queue đầy ?
int IsFull(const QUEUE &q)
{
if (q.NumItems==q.Max)
return 1; // Queue đầy
return 0; // Queue không đầy
}
3.2.4. Hàm thêm một phần tử vào cuối Queue
// 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.Rear++;
if (q.Rear==q.Max) // “tràn giả”
q.Rear = 0; // Quay trở về đầu mảng
q.QArray[q.Rear] = newitem; // thêm phần tử vào Queue
if (q.NumItems==0)
q.Front = 0;
q.NumItems++;
return 1; // Thêm thành công
}
3.2.5. Hàm lấy một phần tử ở đầu Queue
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 4
HDTH CTDL & KTLT nâng cao tuần 5
// 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, kết quả=FALSE
itemout = q.QArray[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; // Thêm thành công
}
3.2.6. Hàm lấy về một phần tử ở đầu Queue mà không xóa phần tử đó
// Thao tác “QueueFront”: kiểm tra phần tử ở đầu Queue
// *** không xoá phần tử
int QueueFront(const QUEUE &q, int &itemout)
{
if (IsEmpty(q))
return 0; // Queue rỗng, kết quả=FALSE
// lấy phần tử đầu ra
itemout = q.QArray[q.Front];
return 1;
}
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 5
HDTH CTDL & KTLT nâng cao tuần 5
4. Xây dựng Queue bằng danh sách liên kết đơn
Tương tự như phần xây dựng Queue bằng mảng ta cũng tiến hành như sau.
4.1. Khai báo cấu trúc Queue bằng struct
// Giả sử Queue chứa các phần tử kiểu phân số
4.2. Các hàm xử lý thao tác
void InitQueue(QUEUE &q);
int IsEmpty(const QUEUE &q);
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 6
HDTH CTDL & KTLT nâng cao tuần 5
int EnQueue(QUEUE &q, NODE* p);
int DeQueue(QUEUE &q, NODE* &p);
int QueueFront(QUEUE &q, NODE* &p);
4.2.1. Hàm khởi tạo Queue
4.2.2. Hàm kiểm tra Queue rỗng
4.2.3. Hàm thêm một phần tử vào cuối Queue
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 7
HDTH CTDL & KTLT nâng cao tuần 5
4.2.4. Hàm lấy một phần tử ở đầu Queue
4.2.5. Hàm lấy về một phần tử ở đầu Queue mà không xóa phần tử đó
4.3. Các hàm phụ trợ khác
4.3.1. Hàm nhập vào danh sách vào Queue
void input(QUEUE &q){
int n;printf ("Nhap vao so luong node (phan so):");scanf("%d",&n);phanso x;for(int i=1; i<=n;i++){
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 8
HDTH CTDL & KTLT nâng cao tuần 5
printf("Nhap vao tu so:");scanf("%d",&x.tu);printf("Nhap vao mau so:");scanf("%d",&x.mau);EnQueue(q,x); // đẩy phân số mới nhập vào Queue
}}
4.3.3. Hàm xuất ra danh sách từ Queue
4.3.4. Hàm main
Bài Tập
Bài tập về Queue dùng danh sách liên kết đơn để quản lý nhân viên
1. Tạo cấu trúc nhân viên gồm tên, tuổi, lương.
2. Tạo cấu trúc node để lưu trữ mỗi node là một nhân viên tương ứng.
3. Tạo cấu trúc Queue.
4. Khởi tạo Queue rỗng (hàm InitQueue).
5. Viết hàm kiểm tra Queue có rỗng hay không? (IsEmpty).
6. Viết hàm nhập các thông tin nhân viên.
7. Viết hàm thêm một node nhân viên vào cuối Queue (EnQueue).
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 9
HDTH CTDL & KTLT nâng cao tuần 5
8. Viết hàm lấy một node nhân viên ở đầu Queue ra (DeQueue).
9. Viết hàm hàm lấy một node nhân viên ở đỉnh Queue ra mà không xóa node đó khỏi
Queue (QueueFront).
10. Viết nhập một danh sách thông tin nhân viên vào trong Queue.
11. Viết hàm hiển thị thông tin nhân viên trong Queue ra.
Nguyễn Kim Hưng – Đoàn Chánh Thức – Khoa CNTT 10