/////////////////////////////////////////////////////////// 
//--------------------------------------------------------- 
//            循环队列存储结构及基本操作 
//--------------------------------------------------------- 
/////////////////////////////////////////////////////////// 

#include<stdio.h> 
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#include<ctype.h>

//以下为函数运行结果状态代码 
#define TRUE 1
#define FALSE 0
#define OK 1 
#define ERROR 0 
#define INFEASIBLE -1 
#define OVERFLOW -2 

#define MAXQSIZE 100  //最大队列长度 

typedef int Status; //函数类型，其值为函数结果状态代码
typedef int QElemType; //数据类型定位整型 
typedef struct {
	QElemType * base;//初始化的动态分配存储空间 
	int front;//头指针，若队列不空，指向队列头元素 
	int rear;//尾指针，若队列不空，指向队列尾元素的下一个位置
}SqQueue; 

//-------------基本操作的函数原型说明----------------
Status InitQueue(SqQueue &Q);
Status DestroyQueue(SqQueue &Q);
Status ClearQueue(SqQueue &Q);
Status QueueEmpty(SqQueue Q);
int QueueLength(SqQueue Q);
Status GetHead(SqQueue Q,QElemType &e);
Status EnQueue(SqQueue &Q,QElemType e);
Status DeQueue(SqQueue &Q,QElemType &e);
Status QueueTravserse(SqQueue Q);


//-----------基本操作的算法----------------
Status InitQueue(SqQueue &Q){
	//构造一个空队列
	Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
	if(!Q.base) exit(OVERFLOW);//存储分配失败
	Q.front=0;
	Q.rear=0;
	return OK;
}

Status DestroyQueue(SqQueue &Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	int i;
	for(i=0;i<MAXQSIZE;i++){
		free(Q.base);
		Q.base++;
	}
	Q.base=NULL;
	return OK;
}

Status ClearQueue(SqQueue &Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	int i;
	for(i=0;i<MAXQSIZE;i++){
	Q.base[i]=0;
	}
	Q.front=0;
	Q.rear=0;
	return OK;
}

Status QueueEmpty(SqQueue Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if(Q.front==Q.rear) return TRUE;
	else return FALSE;
}

int QueueLength(SqQueue Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

Status GetHead(SqQueue Q,QElemType &e){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if(Q.rear==Q.front) return OVERFLOW;//队列为空
	e=Q.base[Q.front];
	return OK;
}

Status EnQueue(SqQueue &Q,QElemType e){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;//队列已满
	Q.base[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAXQSIZE;
	return OK;
}

Status DeQueue(SqQueue &Q,QElemType &e){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if(Q.front==Q.rear) return ERROR;//队列为空
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%MAXQSIZE;
	return OK;
}

Status QueueTravserse(SqQueue Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if(Q.front==Q.rear) return OVERFLOW;//队列为空
	int i;
	printf("\n-----------all elements -----------------------\n");
	for(i=Q.front;i!=Q.rear;){
		printf("%d\t",Q.base[i]);
		i=(i+1)%MAXQSIZE;
	}
	printf("\n------------------ end ------------------------\n");
	return OK;
}

Status ReadF(SqQueue &Q){
	//
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	int i=0;
	FILE *fp;
	if((fp=fopen("data.dat","r"))==NULL){
		printf("FILE OPEN ERROR\n");
		return ERROR;
	}
	while(fread(Q.base+i,sizeof(QElemType),1,fp)){
		i++;
	}
	fclose(fp);
	Q.front=0;
	Q.rear=i;
	return OK;
}

Status SaveFile(SqQueue&Q){
	FILE *fp;
	if(Q.base==NULL) return INFEASIBLE;//队列不存在
	if((fp=fopen("data.dat","w"))==NULL){
		printf("File open error\n");
		return ERROR;
	}
	int i;
	i=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
	fwrite(Q.base,sizeof(QElemType),i,fp);
	fclose(fp);
	return OK;	
}

int main(){
	SqQueue Q;
	Q.base=NULL;
	QElemType e;
	int op=1;
	while(op){
		system("cls");
		printf("\n\n");
		printf("      Menu for Linear Table On Sequence Structure \n");
		printf("-------------------------------------------------\n");
		printf("    	  1. IntiaQueue       7. EnQueue\n");
		printf("    	  2. DestroyQueue     8. DeQueue \n");
		printf("    	  3. ClearQueue       9. QueueTravserse\n");
		printf("    	  4. QueueEmpty       10. SaveFile\n");
		printf("    	  5. QueueLength      11. ReadFile\n");
		printf("    	  6. GetHead\n");
		printf("    	  0. Exit\n");
		printf("-------------------------------------------------\n");
		printf("    请选择你的操作[0~11]:");
		scanf("%d",&op);
		switch(op){
			case 1:
				if(InitQueue(Q)) printf("队列创建成功！\n");
				else printf("队列创建失败！\n");
				getchar();getchar();
				break;
			case 2:
				if(DestroyQueue(Q)==INFEASIBLE) printf("队列不存在\n");
				else printf("队列销毁成功\n");
				getchar();getchar();
				break;
			case 3:
				{
					int i=0;
					i=ClearQueue(Q);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else printf("队列已清空\n");
					getchar();getchar();
				}
				break;
			case 4:
				{
					int i=0;
					i=QueueEmpty(Q);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else if(i==TRUE) printf("队列是空的\n");
					else if(i==FALSE) printf("队列不是空的\n");
					getchar();getchar();
				}
				break;
			case 5:
				{
					int i=0;
					i=QueueLength(Q);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else printf("队列长度为%d\n",i);
					getchar();getchar();
				}
				break;
			case 6:
				{
					int i=0;
					i=GetHead(Q,e);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else if(i==OVERFLOW)printf("队列为空\n");
					else printf("队列首元素为%d\n",e);
					getchar();getchar();
				}
				break;
			case 7:
				{
					int i=0;
					printf("请输入要入队列的值:");
					getchar();
					scanf("%d",&e);
					i=EnQueue(Q,e);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else if(i==ERROR)printf("队列已满\n");
					else printf("%d入队列成功\n",e);
					getchar();getchar();
				}
				break;
			case 8:
				{
					int i=0;
					i=DeQueue(Q,e);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else if(i==ERROR)printf("队列为空\n");
					else printf("%d出队列成功\n",e);
					getchar();getchar();
				}
				break;
			case 9:
				{
					int i=0;
					printf("");
					i=QueueTravserse(Q);
					if(i==INFEASIBLE) printf("队列不存在\n");
					else if(i==OVERFLOW)printf("队列为空\n");
					getchar();getchar();
				}
				break;
			case 10:
				{
					int i;
					i=SaveFile(Q);
					if(i==OK) printf("文件保存成功");
					else if(i==INFEASIBLE) printf("队列不存在！");
					else printf("文件保存失败！");
					getchar();getchar();
				}
				break;
			case 11:
				{
					int i;
					i= ReadF(Q);
					if(i==OK) printf("文件读取成功");
					else if(i==INFEASIBLE) printf("队列不存在！");
					else printf("文件读取失败！");
					getchar();getchar();
				}
				break;
		}	
	}
}


















