Để cài đặt hàng đợi bằng danh sách liên kết, ta cũng sử dụng 1 danh sách liên kết đơn và 2 con trỏ head và tail lưu giữ nút đầu và nút cuối của danh sách. Việc bổ sung phần tử mới sẽ được tiến hành ở cuối danh sách và việc lấy phần tử ra sẽ được tiến hành ở đầu danh sách.
Hình 4.4 Cài đặt hàng đợi bằng danh sách liên kết Khai báo 1 hàng đợi bằng danh sách liên kết như sau:
struct node { int item;
struct node *next; };
typedef struct node *queuenode; typedef struct {
queuenode head; queuenode tail; }queue;
Khai báo tương tự như ngăn xếp, tuy nhiên, hàng đợi sử dụng 2 biến là hea và tail để lưu giữ điểm đầu và điểm cuối của hàng. Khi đó, các thao tác trên hàng đợi được cài đặt như sau:
Thao tác khởi tạo hàng đợi
Thao tác này thực hiện việc gán giá trị null cho nút đầu và cuối của hàng đợi, cho biết hàng đợi đang ở trạng thái rỗng.
void QueueInitialize(queue *q){ q-> head = q-> tail = NULL; return; } NULL head … tail
68
Thao tác kiểm tra hàng đợi rỗng
Hàng đợi rỗng nếu nút đầu trỏ đến NULL.
int QueueEmpty(queue q){ return (q.head == NULL); }
Thao tác thêm 1 phần tử vào hàng đợi
void Put(queue *q, int x){ queuenode p;
p = (queuenode) malloc (sizeof(struct node)); p-> item = x;
p-> next = NULL; q-> tail-> next = p;
q-> tail = q-> tail-> next;
if (q-> head == NULL) q-> head = q-> tail; return;
}
Để thêm phần tử vào cuối hàng đợi, tạo và cấp phát bộ nhớ cho 1 nút mới. Gán giá trị thích hợp cho nút này, sau đó cho con trỏ tiếp của nút cuối hàng đợi trỏ đến nó. Nút này bây giờ trở thành nút cuối của hàng đợi. Nếu hàng đợi chưa có phần tử nào thì nó cũng chính là nút đầu của hàng đợi.
Lấy phần tử ra khỏi hàng đợi
Để lấy phần tử ra khỏi hàng đợi, tiến hành lấy phần tử tại vị trí nút đầu và cho nút đầu chuyển về nút kế tiếp. Tuy nhiên, trước khi làm các thao tác này, ta phải kiểm tra xem hàng đợi có rỗng hay không.
int Get(queue *q){ queuenode p;
if (QueueEmpty(*q)){
printf("Ngan xep rong !"); return 0;
}else{
p = q-> head;
q-> head = q-> head-> next; return p->item;
} }