您的位置:首页 > 编程语言 > C语言/C++

链式队列定义以及应用

2016-10-18 23:11 363 查看
   利用队列的链式存储结构,设计一组输入数据(假定为一组整数),能够对链式队列进行如下操作:

    初始化一个空队列,形成一个带表头结点的空队;

    完成一个元素的入队操作,修改队尾指针;

    完成一个元素的出队操作,修改队头指针;

    修改主程序,实现对各不同的算法调用。

(1)   首先将链式队列的存储结构定义放在一个头文件:如取名为LinkQueueDef.h。

(2)   将链式队列的基本操作算法也集中放在一个文件之中,如取名为LinkQueueAlgo.h。如:InitQueue、DestroyQueue、ClearQueue、QueueEmpty、QueueLength、GetHead_Q、EnQueue、DeQueue、QueueTraverse等。

(3)   将函数的测试和主函数组合成一个文件,如取名为LinkQueueUse.cpp。

pubuse.h

#include<string.h>
#include<ctype.h>
#include<malloc.h>/*malloc()等*/
#include<limits.h>/*INT_MAX等*/
#include<stdio.h>/*EOF(=^Z或F6),NULL*/
#include<stdlib.h>/*atoi()*/
#include<io.h>/*eof()*/
#include<math.h>/*floor(),ceil(),abs()*/
#include<process.h>/*exit()*/
/*函数结果状态代码*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/*#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行*/
typedef int Status;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedef int Boolean;/*Boolean是布尔类型,其值是TRUE或FALSE*/


LinkQueueDef.h中实现单链队列--队列的链式存储结构的表示

typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;

typedef struct{
QueuePtr front,rear;/*队头、队尾指针*/
}LinkQueue;

 对链式队列的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价。

  “初始化空队算法”操作结果:构造一个空队列Q;

  “销毁队列算法”操作结果:销毁队列Q(无论空否均可);

  “空队列算法”操作结果:将Q清为空队列;

  “判队列是否为空算法”操作结果:若Q为空队列,则返回TRUE,否则返回FALSE;

  “求队列的长度算法”操作结果:求队列的长度,返回队列中结点的个数;

  “取队头元素算法”操作结果:若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR;

  “入队算法”操作结果:插入元素e为Q的新的队尾元素;

  “出队算法”操作结果:若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR;

LinkQueueAlgo.h中实现的链队列的基本算法,其存储结构由LinkQueueDef.h定义。

Status InitQueue(LinkQueue &Q)
{/*构造一个空队列Q*/
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)
exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue &Q)
{/*销毁队列Q(无论空否均可)*/
while(Q.front){
Q.rear=Q.front->next;
free(Q.front);Q.front=Q.rear;
}
return OK;
}
Status ClearQueue(LinkQueue &Q){/*将Q清为空队列*/
QueuePtr p,q;Q.rear=Q.front;p=Q.front->next;
Q.front->next=NULL;while(p){q=p;p=p->next;free(q);
}
return OK;
}
Status QueueEmpty(LinkQueue Q)
{/*若Q为空队列,则返回TRUE,否则返回FALSE*/
if(Q.front==Q.rear)return TRUE;
else return FALSE;}
int QueueLength(LinkQueue Q)
{/*求队列的长度*/
int i=0;QueuePtr p;p=Q.front;
while(Q.rear!=p){i++;p=p->next;}
return i;
}
Status GetHead_Q(LinkQueue Q,QElemType&e)
{/*若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR*/
QueuePtr p;if(Q.front==Q.rear)return ERROR;
p=Q.front->next;e=p->data;return OK;
}
Status EnQueue(LinkQueue &Q,QElemType e)
{/*插入元素e为Q的新的队尾元素*/
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p)/*存储分配失败*/
exit(OVERFLOW);
p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;
return OK;
}
Status DeQueue(LinkQueue &Q,QElemType &e)
{/*若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR*/
QueuePtr p;
if(Q.front==Q.rear)return ERROR;
p=Q.front->next;e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;free(p);
return OK;
}
Status QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
{/*从队头到队尾依次对队列Q中每个元素调用函数vi()。一旦vi失败,则操作失败*/
QueuePtr p;p=Q.front->next;
while(p){
vi(p->data);p=p->next;
}
printf("\n");
return OK;
}


LinkQueueUse.cpp中包含检验LinkQueueAlgo.h中关于链式队列基本操作的声明、测试数据和主函数。

#include"pubuse.h"/*与实验一的意义相同*/
typedef int QElemType;/*假设链式队列中的结点是一组整数
*/
#include"linkqueuedef.h"
#include"linkqueuealgo.h"
void visit(QElemType i)
{
printf("%d",i);
}
int main()
{
int i;QElemType d;LinkQueue q;
i=InitQueue(q);
if(i)
printf("成功地构造了一个空队列!\n");
printf("是否空队列?%d(1:空0:否)",QueueEmpty(q));
printf("队列的长度为%d\n",QueueLength(q));
EnQueue(q,-5);EnQueue(q,5);EnQueue(q,10);
printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(q));
printf("是否空队列?%d(1:空0:否)",QueueEmpty(q));
printf("队列的元素依次为:");
QueueTraverse(q,visit);
i=GetHead_Q(q,d);
if(i==OK)printf("队头元素是:%d\n",d);
DeQueue(q,d);
printf("删除了队头元素%d\n",d);
i=GetHead_Q(q,d);
if(i==OK)printf("新的队头元素是:%d\n",d);
ClearQueue(q);
printf("清空队列后,q.front=%u q.rear=%u q.front->next=%u\n",q.front,q.rear,q.front->next);DestroyQueue(q);
printf("销毁队列后,q.front=%u q.rear=%u\n",q.front,q.rear);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息