数据节点
//有效数据节点结构体设计
typedef struct Lqueue
{
ELEM_TYPE data;//数据域
Lqueue *next;//指针域
}Lqueue, *PLqueue;
头节点
typedef struct Head
{
Lqueue *front;//指针域 指向第一个有效数据节点
Lqueue *tail; //指针域 指向最后一个有效数据节点
}Head, *PHead;
初始化
void Init_lqueue(PHead pq) {
assert(pq != NULL);
Lqueue* lq = (Lqueue*)malloc(sizeof(Lqueue));
if (lq == NULL) {
exit(EXIT_FAILURE);
}
pq->front = lq;
pq->tail = lq;
lq->next = NULL;
}
为满足队列结构 初始化使PHead的头节点和尾节点同时指向一个空数据节点 此时申请到的节点即是front又是tail同时还是第一个(空)数据节点 使后续操作更加方便
入队(尾节点插入)
bool Push(PHead pq, ELEM_TYPE val) {
assert(pq != NULL);
Lqueue* lq = (Lqueue*)malloc(sizeof(Lqueue));
if (lq == NULL) {
exit(EXIT_FAILURE);
}
lq->data = val;
pq->tail->next=lq;
pq->tail = lq;
pq->tail->next = NULL;
return true;
}
出队
bool Pop(PHead pq, ELEM_TYPE* rtval) {
assert(pq != NULL);
if ((IsEmpty(pq))) {
return false;
}
//此处应注意 当队列只剩下一个数据节点时 要将 尾节点tail指针移动到头节点位置 此时与front指针与tail指针的状态与初始化时相同 队列此时为空
if (pq->front->next == pq->tail) {
pq->tail = pq->front;
}
Lqueue* p = pq->front->next;
*rtval = p->data;
pq->front->next = p->next;
free(p);
return true;
}
如果出队成功需要返回出队的值 rtval 用来保存出队的值
获取队头元素 同样用rtval来接收
bool Top(PHead pq, ELEM_TYPE* rtval) {
assert(pq != NULL);
if (IsEmpty(pq)) {
return false;
}
*rtval = pq->front->next->data;
return true;
}
其他函数
//获取有效值个数
int Get_length(PHead pq) {
assert(pq != NULL);
int count = 0;
for (Lqueue* p = pq->front->next; p != NULL; p = p->next) {
count++;
}
return count;
}
//判空
bool IsEmpty(PHead pq) {
return pq->front == pq->tail;
}
//清空
void Clear(PHead pq) {
Destroy(pq);
}
//销毁
void Destroy(PHead pq) {
assert(pq != NULL);
int tem;
while (IsEmpty(pq)) {
Pop(pq,&tem);
}
free(pq->front);
pq->front = NULL;
}
//打印
void Show(PHead pq) {
assert(pq != NULL);
for (Lqueue* p = pq->front->next; p != NULL; p = p->next) {
printf("%d ", p->data);
}
printf("\n");
}