/*
不带头结点的链队操作集(无 initFlag 标志变量版本)
1、初始化链队 Q Status InitQueue_LQ(LQueue &Q);
2、销毁链队 Q Status DestroyQueue_LQ(LQueue &Q);
3、判断链队 Q 是否为空 Status QueueEmpty_LQ(LQueue Q);
4、清空链队 Q Status ClearQueue_LQ(LQueue &Q);
5、入队操作 Status EnQueue_LQ(LQueue &Q, ElemType e);
6、出队操作 Status DeQueue_LQ(LQueue &Q, ElemType &e);
7、读取队头元素 Status GetHead_LQ(LQueue Q, ElemType &e);
*/
#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define PERROR -2
typedef int Status;
// 定义数据元素类型
typedef int ElemType;
// 定义链表结点类型
typedef struct LQNode{
ElemType data;
struct LQNode *next;
}LQNode, *LQNodePtr;
// 定义链队类型:front 队头指针,rear 队尾指针
typedef struct{
LQNodePtr front;
LQNodePtr rear;
}LQueue;
// 1、初始化链队:front、rear 均置 NULL
Status InitQueue_LQ(LQueue &Q){
Q.front = NULL;
Q.rear = NULL;
return OK;
}
// 2、销毁链队:从头结点开始逐个释放,最后 front/rear 置 NULL
Status DestroyQueue_LQ(LQueue &Q){
LQNodePtr p;
while(Q.front != NULL){
p = Q.front->next;
free(Q.front);
Q.front = p;
}
Q.front = NULL;
Q.rear = NULL;
return OK;
}
// 3、判断链队是否为空:空返回 TRUE,非空返回 FALSE
Status QueueEmpty_LQ(LQueue Q){
if(Q.front == NULL)
return TRUE;
else
return FALSE;
}
// 4、清空链队:释放所有数据结点,队列结构保留,可继续入队
Status ClearQueue_LQ(LQueue &Q){
LQNodePtr p;
while(Q.front != NULL){
p = Q.front;
Q.front = p->next;
free(p);
}
Q.rear = NULL;
return OK;
}
// 5、入队:队空时新结点同时作 front 和 rear;非空时接到 rear->next
Status EnQueue_LQ(LQueue &Q, ElemType e){
LQNodePtr p;
p = (LQNodePtr)malloc(sizeof(LQNode));
if(p == NULL) return OVERFLOW; // 内存分配失败
p->data = e;
p->next = NULL;
if(Q.front == NULL){ // 队空
Q.front = p;
}else{ // 队非空,接到队尾
Q.rear->next = p;
}
Q.rear = p;
return OK;
}
// 6、出队:删除队头结点;若删除的是最后一个结点,rear 同步置 NULL
Status DeQueue_LQ(LQueue &Q, ElemType &e){
LQNodePtr p;
if(Q.front == NULL) return ERROR; // 队空,不能出队
p = Q.front;
e = p->data;
Q.front = p->next;
if(Q.rear == p){ // 删除后变空
Q.rear = NULL;
}
free(p);
return OK;
}
// 7、读取队头元素(不删除)
Status GetHead_LQ(LQueue Q, ElemType &e){
if(Q.front == NULL) return ERROR; // 队空,不能读取
e = Q.front->data;
return OK;
}
int main(){
int i, e, state;
LQueue Q;
InitQueue_LQ(Q); // 使用前先初始化,避免 front/rear 为野指针
printf("==== 不带头结点链队操作 ====\n");
printf("1.初始化队列\n");
printf("2.销毁队列\n");
printf("3.判断队列是否为空\n");
printf("4.清空队列\n");
printf("5.将元素入队\n");
printf("6.队头元素出队\n");
printf("7.取队头元素\n");
do{
printf("\n请输入你要进行的操作:\n");
scanf("%d", &i);
switch(i){
case 1:
InitQueue_LQ(Q);
printf("队列初始化成功。\n");
break;
case 2:
DestroyQueue_LQ(Q);
printf("队列销毁成功。\n");
break;
case 3:
state = QueueEmpty_LQ(Q);
if(state == TRUE)
printf("队列为空!\n");
else
printf("队列不为空!\n");
break;
case 4:
ClearQueue_LQ(Q);
printf("已为您清空队列。\n");
break;
case 5:
printf("请输入将要入队的元素的值:\n");
scanf("%d", &e);
state = EnQueue_LQ(Q, e);
if(state == OK)
printf("元素 %d 成功入队。\n", e);
else if(state == OVERFLOW)
printf("内存不足,入队失败!\n");
break;
case 6:
state = DeQueue_LQ(Q, e);
if(state == OK)
printf("元素 %d 成功出队!\n", e);
else
printf("队列内没有元素,不能执行出队操作!\n");
break;
case 7:
state = GetHead_LQ(Q, e);
if(state == OK)
printf("队头元素的值为:%d\n", e);
else
printf("队列内没有元素,不能读取队头!\n");
break;
}
}while(i >= 1 && i <= 7);
return 0;
}