循环队列的改进

来源:互联网 发布:淘宝上新后怎么改价格 编辑:程序博客网 时间:2024/06/06 20:29

 

在学习《数据结构》这门课的时候,书中给出了循环队列的两种结构:

1. 少用一个空间,以避免循环队列“满”状态和“空”状态(如图1)的冲突。

1

代码为:

#define    MAXSIZE50                                     //队列的最大长度

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,QElemTypex)

{

       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;

}

通过比较,我认为:方法31优于2,方法3在空间利用上优于方法2,方法2在运算上优于方法3

下面是所有文件下载的路径:http://forum.clwind.net/job-htm-action-download-pid-tpc-tid-175229-aid-92766.html