循环队列的存储设计实现(C语言版)

1.概念

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

    循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。使用求余运算可以判断队列是否已满。

基本操作:

/* 定义链表队列 */

定义结构体中front指示队头位置,rear指示队尾位置,base指针用于申请空间并存放数据。

循环队列的存储设计实现(C语言版)_第1张图片

/* 初始化队列 */

使用指针*base申请100个内存空间,front和rear分别为0,此时队列为空

/* 判断空或满 */

  • 初始化时, front = rear = 0  时为空, Q->rear =  0+1 %100 = 1 ,队列未满可以插入队列

    循环队列的存储设计实现(C语言版)_第2张图片

  • 入队 3 个元素时, rear = 3 Q->rear =  3+1 %100 = 4 ,队列未满

    循环队列的存储设计实现(C语言版)_第3张图片

  • 入队 99 个元素时, rear = 99 Q->rear =  99+1 %100 = 0 ,队列满,不可入队

    循环队列的存储设计实现(C语言版)_第4张图片

  • 出队 2 个元素时, front = 2

    出队后,执行两次 Q->front = (Q->front + 1) % MAXQSIZE,得到Q->front = 2

    循环队列的存储设计实现(C语言版)_第5张图片

  • 再次入队 1 个元素时, rear = 0 Q->rear =  99+1 %100=0 ,队列未满,可以入队

    循环队列的存储设计实现(C语言版)_第6张图片

  • 通用的计算队列长度公式:(rear-front+QueueSize)%QueueSize

  • #include 
    #include 
    #define OK 1
    #define ERROR 0
    #define OVERFLOW -2
    #define MAXQSIZE 10
    typedef int Status;
    typedef int QElemType;
    
    //循环队列的顺序存储结构
    typedef struct Node
    {
    	QElemType *base; //初始化动态分配存储空间
    	int front;//头指针
    	int rear;//尾指针-若队列不空,指向队列尾元素的下一个位置
    } SqQueue;
    
    //初始化一个空的队列
    Status InitQueue(SqQueue *Q)
    {
    	Q->base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
    	if (!Q->base)
    		exit(OVERFLOW);
    	Q->front = Q->rear = 0;
    	return OK;
    }
    //若队列未满 则插入元素elem为Q新的队尾元素
    Status EnQueue(SqQueue *Q, QElemType elem)
    {
    	//队列为空时 1%10==1,队列满时(9+1)%100==0,最多容纳9个元素
    	if ((Q->rear + 1) % MAXQSIZE == (Q->front))//队列满的判断
    		return ERROR;
    	Q->base[Q->rear] = elem;//将元素elem赋值给队尾
    	Q->rear = (Q->rear + 1) % MAXQSIZE; //rear始终在0-10中循环
    	return OK;
    }
    //循环队列的出队列操作代码
    Status OutQueue(SqQueue *Q, QElemType *e)
    {
    	if (Q->front == Q->rear)//队列为空的判断
    		return ERROR;
    	*e = Q->base[Q->front];//将队头元素赋值给元素e
    	Q->front = (Q->front + 1) % MAXQSIZE;//front指针像后移一位置
    	return OK;
    }
    
    //遍历整个队列,进行打印操作
    Status PrintQueue(SqQueue Q)
    {
    	printf("the queue is:");
    	for (int i = Q.front; i < Q.rear; ++i)
    		printf("%d ", Q.base[i]);
    	return OK;
    }
    int main()
    {
    	SqQueue queue;
    	QElemType elem;
    	int i;
    	InitQueue(&queue);
    	printf("input:");
    	for ( i = 0; i < 10; i++)
    	{
    		elem = i + 1;
    		EnQueue(&queue, elem);
    	}
    
    	PrintQueue(queue);
    	/* 输入要出队列的个数 */
    	printf("\noutput:");
    	scanf("%d", &i);
    	while (i != 0)
    	{
    		OutQueue(&queue, &elem);
    		i--;
    	}
    	PrintQueue(queue);
    	return OK;
    }


你可能感兴趣的:(数据结构)