在学习《数据结构》这门课的时候,书中给出了循环队列的两种结构:
1. 少用一个空间,以避免循环队列“满”状态和“空”状态(如图1)的冲突。
图1
代码为:
#define MAXSIZE 50 //队列的最大长度
typedefy struct
{
QueueElementType element[MAXSIZE ]; //队列的元素空间
int front; //头指针指示器
int rear; //尾指针指示器
}SeqQueue;
“空”状态:front==rear
“满”状态:(rear+1)% MAXSIZE==front
2. 另一种是增设一个标志量,以区别队列是“空”还是“满”。
这两种方法都存在内存的浪费的问题,我想到了一个方法,可以解决这个问题:
在初始化队列时,设front = 0 rear = -1,队列要变为空的时候,也将队列变为这种状态。
当队列满的时候(rear+1)% MAXSIZE = = front。队列为空时,同样满足这个公式。可是,队列满的时候rear总是为正整数,而队列为空时,rear总为 -1。因此,可以通过这种方法来区别队列“满”和“空”的状态,同时所有的空间都可以被使用。
下面是以上三种方法的全部代码:
1) queue_seq_1.h
//少用一个空间的循环队列
#define MAXSIZE 50 //队列的最大长度
typedef struct
{
QueueElementType element[MAXSIZE]; //队列的元素空间
int front; //头指针指示量
int rear; //尾指针指示量
}SeqQueue;
void InitQueue ( SeqQueue *Q ) //初始化 *Q
{
Q->front = Q->rear = 0;
}
int EnterQueue ( SeqQueue *Q, QueueElementType x ) //将x入队
{
if ( ( Q->rear + 1 )%MAXSIZE == Q->front ) //队列已满
return FALSE;
Q->element[Q->rear] = x;
Q->rear = (Q->rear + 1 )%MAXSIZE; //重新设置尾指针
return TRUE;
}
int DeleteQueue ( SeqQueue *Q, QueueElementType *x )//出队操作
{
if ( Q->front == Q->rear ) //队列为空
return FALSE;
*x = Q->element[ Q->front ];
Q->front = ( Q->front + 1 )%MAXSIZE; //重新设置头指针
return TRUE;
}
2) queue_seq_2.h
//带tag的循环队列
#define MAXSIZE 50 //队列的最大长度
typedef struct
{
QueueElementType element[MAXSIZE]; //队列的元素空间
int front; //头指针指示量
int rear; //尾指针指示量
int tag; //“满”、“空”指示量
}SeqQueue;
void InitQueue ( SeqQueue *Q ) //初始化 *Q
{
Q->front = Q->rear = Q->tag = 0;
}
int EnterQueue ( SeqQueue *Q, QueueElementType x ) //将x入队
{
if ( Q->tag == 1 ) //队列已满
return FALSE;
Q->element[Q->rear] = x;
Q->rear = (Q->rear + 1 )%MAXSIZE; //重新设置尾指针
return TRUE;
}
int DeleteQueue ( SeqQueue *Q, QueueElementType *x )//出队操作
{
if ( Q->front == Q->rear && Q->tag == 0 ) //队列为空
return FALSE;
*x = Q->element[ Q->front ];
uot;> Q->front = ( Q->front + 1 )%MAXSIZE; //重新设置头指针
return TRUE;
}
3) queue_seq.h
//既不少使用一个空间,也不另设tag项的循环队列
#define MAXSIZE 50
typedef struct{
QElemType element[MAXSIZE];
int front;
int rear;
}sq,* psq;
void initsq(sq* Q)
{
Q->front=0;
Q->rear=-1;
}
int entersq(sq* Q,QElemType x)
{
if( (Q->rear+1)%MAXSIZE==Q->front && Q->rear!=-1 )
return -1; //队列已满,返回-1,表示出现错误
Q->rear=(Q->rear+1)%MAXSIZE;
Q->element[Q->rear]=x;
return 0;
}
int deletesq(sq* Q,QElemType *x)
{
if(Q->rear==-1) //当队列尾指针为-1的时候,队列为空
return -1;
*x = Q->element[Q->front];
if( Q->front==Q->rear ) //如果队列为空,则变回初始化状态
{
Q->front = 0;
Q->rear = -1;
}
else
Q->front = (Q->front+1)%MAXSIZE;
return 0;
}
通过比较,我认为:方法3、1优于2,方法3在空间利用上优于方法2,方法2在运算上优于方法3。
下面是所有文件下载的路径:http://forum.clwind.net/job-htm-action-download-pid-tpc-tid-175229-aid-92766.html