循环队列的改进

 

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

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;

}

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

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

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值