循环队列拾遗-使用数组实现循环队列

循环队列

为充分利用向量空间,克服”假溢出”现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现。

循环队列的问题

循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。

因此,无法通过条件front==rear来判别队列是”空”还是”满”。

解决这个问题的方法至少有两种:
1. 另设一布尔变量以区别队列的空和满;
2. 另一种方式就是数据结构常用的: 队满时:(rear+1)%n==front,n为队列长度(所用数组大小),由于rear,front均为所用空间的指针,循环只是逻辑上的循环,所以需要求余运算。

话不多说,先贴代码再进行解释

//来自于http://blog.csdn.net/nyhuachen/article/details/6422352
/************************************************************************/
/* author : thomas
   E-mail: [email protected]                                         */
/************************************************************************/
//循环队列(数组实现)
#include 
#include 
#define MAXSIZE 5
typedef int T;
typedef struct tag
{
    int front, rear, MaxSize, count; //其实MaxSize变量完全可以不要
    T elements[MAXSIZE];
} QUEUE;

定义了使用到的变量,包括front\rear\count等
front指定队首位置,删除一个元素就将front顺时针移动一位;
rear指向元素要插入的位置,插入一个元素就将rear顺时针移动一位;
count存放队列中元素的个数,当count等于MaxSize时,不可再向队列中插入元素。

void creat( QUEUE *queue )
{
    queue -> front = 0;
    queue -> rear = 0;
    queue -> count = 0;
    queue -> MaxSize = MAXSIZE - 1;
}

这个应该类似于java中的构造函数

int is_empty( QUEUE queue)  //其实最好传指针免得栈开销太大
{
    if ( queue.count == 0 )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
int is_full( QUEUE queue )
{
    if ( queue.count == MAXSIZE )
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

这是用了第一种判断队列满的方式,只不过把bool型的变量转换成了MAXSIZE以及count这两个变量的求是否相等。

void readqueue( QUEUE queue ) //just read the value
{
    if ( queue.count == 0 )  //可以用前面的is_empty函数进行判断
    {
        printf("the queue is empty! no number is available! /n");
    }
    else
    {
        printf("the first number is %d /n", queue.elements[queue.front]);
    }
}
void in_queue( QUEUE *queue, T value )
{
    if ( queue -> count == MAXSIZE )  //可以利用前面的is_full函数进行判断
    {
        printf("sorry! the queue is full! no space is available!/n");
    }
    else
    {
        if ( queue -> count == 0 )
        {
            //主要是处理队列为空时的入队列
            queue -> elements[queue -> rear] = value;
            queue -> count += 1;
        }
        else
        {
            queue -> rear = (queue -> rear + 1) % MAXSIZE;
            queue -> elements[queue ->rear] = value;
            queue -> count += 1;
        }
    }
}
T out_queue( QUEUE *queue )
{
    if ( queue -> count == 0 )  //可以利用前面的is_empty函数进行判断
    {
        printf("sorry! the queue is empty! no number is available! /n");
        exit(EXIT_FAILURE);
    }
    else
    {
        queue -> front = (queue -> front + 1) % MAXSIZE;
        queue -> count -= 1;
        return queue -> elements[queue -> front];
    }
}
//print queue
void print( QUEUE queue )
{
    int i = 1;/*count var*/
    if ( queue.count == 0 )
    {
        printf("the queue is empty! no number can be printed! /n");
    }
    else
    {
        //count = queue.count;
        printf("the number of queue is %d /n", queue.count);
        for ( i; i <= queue.count; i++ )
        {
            printf("the %d number is %d /n", i, queue.elements[(queue.front + i - 1) % MAXSIZE]);
            //printf("the %d number is %d /n", i, queue.elements[queue.front + i - 1]);
        }
    }
}
//test functions
void main(int argc, char *argv[])
{
    QUEUE queue;
    creat(&queue);
    //out_queue(&queue);
    in_queue(&queue, 2);
    print(queue);
    in_queue(&queue, 4);
    print(queue);
    in_queue(&queue, 5);
    print(queue);
    in_queue(&queue, 6);
    print(queue);
    in_queue(&queue, 1);
    print(queue);
    out_queue(&queue);
    print(queue);
    in_queue(&queue, 9);
    print(queue);
    //out_queue(&queue);
    //print(queue);
    in_queue(&queue, 7);
    //print(queue);
}

其实这篇文章也想汇总下第二种方法对循环队列判断是否满的解释:
也即是
–>队满时: (rear+1)%maxsize=front

–>队空时:rear=front

–>正常时:

这部分是http://blog.csdn.net/huangkq1989/article/details/5719529在其的文章处提到的

关键在于少用一个位置,用这个位置为条件将循环队列的逻辑循环(故之只能用%计算)显式地表述出来。

有的时候退一步更能海阔天空=V=

你可能感兴趣的:(数据结构学习,数组,循环队列,数据结构,存储)