/*
本版本加入了针对销毁队列和判空队列的区别处理,引入了 initFlag。
改良后的不带头结点的链队的操作集中包含的操作
1、初始化链队 Q
Status InitQueue_LQ(LQueue &Q, bool &initFlag);
2、销毁链队 Q
Status DestroyQueue_LQ(LQueue &Q, bool &initFlag);
3、判断链队 Q 是否为空
Status QueueEmpty_LQ(LQueue Q, bool initFlag);
4、清空链队 Q
Status ClearQueue_LQ(LQueue &Q, bool initFlag);
5、入队操作
Status EnQueue_LQ(LQueue &Q, bool initFlag, ElemType e);
6、出队操作
Status DeQueue_LQ(LQueue &Q, bool initFlag, ElemType &e);
7、读取队头元素,并用 e 返回
Status GetHead_LQ(LQueue Q, bool initFlag, 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; // 结点及指针类型
// 链队结构类型定义
typedef struct{
LQNodePtr front; // 队头指针
LQNodePtr rear; // 队尾指针
}LQueue; // 链队类型
// 1、链队初始化
Status InitQueue_LQ(LQueue &Q, bool &initFlag){
Q.front = NULL; // 因为还没有结点,所以将队头指针置为 NULL
Q.rear = NULL; // 因为还没有结点,所以将队为指针置为 NULL
initFlag = TRUE; // 标志队列已初始化;
return OK;
}
// 2、销毁链队
Status DestroyQueue_LQ(LQueue &Q, bool &initFlag){
if(initFlag == FALSE)return PERROR; // 参数合法性检验,参数非法或已销毁,返回不再执行销毁操作
//从头结点开始,依次队每一个结点释放内存,这里,Q.rear辅助向后传递的一个临时指针使用
while (Q.front!=NULL){
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
Q.front = NULL; // 避免指针悬挂
Q.rear = NULL; // 避免指针悬挂
initFlag = FALSE; // 标志队列已销毁
return OK;
}
// 3、判断链队 Q 是否为空
Status QueueEmpty_LQ(LQueue Q, bool initFlag){
if( initFlag == FALSE)return PERROR; // 参数合法性检验,非法返回参数错误
if(Q.front == NULL){
return TRUE;
}else{
return FALSE;
}
}
// 4、清空链队 Q
Status ClearQueue_LQ(LQueue &Q, bool initFlag){
if( initFlag == FALSE)return PERROR; // 参数合法性检验,非法返回参数错误
Q.front = NULL;
Q.rear = NULL;
return OK;
}
// 5、入队操作
EnQueue_LQ(LQueue &Q, bool initFlag, ElemType e){
if( initFlag == FALSE)return PERROR; // 参数合法性检验,非法返回参数错误
LQNodePtr p;
p = (LQNode *)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、出队操作
Status DeQueue_LQ(LQueue &Q, bool initFlag, ElemType &e){
if( initFlag == FALSE)return PERROR; // 参数合法性检验,非法返回参数错误
LQNodePtr p;
if(Q.front == NULL)return ERROR; // 如果队空,返回,不执行操作
p = Q.front;
e = p->data;
Q.front = p->next; // 移动队头指针,当是最后一个结点时移动后是 NULL
if(Q.rear == p){
Q.rear = NULL; // 如果删除后队空,移动队尾指针置 NULL
}
free(p);
return OK;
}
// 7、读取队头元素,并用 e 返回
Status GetHead_LQ(LQueue Q,bool initFlag, ElemType &e){
if(initFlag == FALSE)return PERROR; // 参数合法性检验,非法返回参数错误
if(Q.front == NULL)return ERROR; // 如果是空队,无法读取,返回错误
LQNodePtr p = Q.front->next;
e = p->data; // 队头元素交给 e
return OK;
}
int main(){
int i, e, state;
LQueue Q;
bool initFlag;
printf("1.初始化队列\n");
printf("2.销毁队列\n");
printf("3.判断队列是否为空\n");
printf("4.清空队列\n");
printf("5.将元素入队\n");
printf("6.队头元素出队\n");
printf("7.取队头元素,并返回\n");
do{
printf("请输入你要进行的操作:\n");
scanf("%d",&i);
switch(i){
case 1 :
state = InitQueue_LQ(Q, initFlag);
if(state == OK){
printf("队列初始化成功。\n");
}else{
printf("队列初始化失败!\n");
}
break;
case 2 :
state = DestroyQueue_LQ(Q, initFlag);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else{
printf("队列销毁成功。\n");
}
break;
case 3 :
state = QueueEmpty_LQ(Q, initFlag);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else if(state == TRUE){
printf("队列为空!\n");
}else if(state == FALSE){
printf("队列不为空!\n");
}
break;
case 4 :
state = ClearQueue_LQ(Q, initFlag);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else{
printf("已为您清空队列。\n");
}
break;
case 5 :
printf("请输入将要入队的元素的值:\n");
scanf("%d",&e);
state = EnQueue_LQ(Q, initFlag, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else if(state == OK){
printf("元素 %d 成功入队。\n",e);
}else{
printf("元素 %d 入队失败!\n",e);
}
break;
case 6 :
state = DeQueue_LQ(Q, initFlag, e);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else if(state == OK){
printf("元素 %d 成功出队!\n",e);
}else{
printf("队列内没有元素,不能执行出队操作!\n");
}
break;
case 7 :
state = GetHead_LQ(Q, initFlag,e);
if(state == PERROR){
printf("请确认参数合法化或者先执行队列的初始化操作!\n");
}else if(state == OK){
printf("取出队头元素的值为:%d\n",e);
}else{
printf("队列内没有元素,不能执行读取队头元素操作!\n");
}
break;
}
}while(i>=1&&i<=7);
return 0;
}