如何实现循环队列

生活中有很多队列的影子,比如打饭排队,买火车票排队问题等,可以说与时间相关的问题,一般都会涉及到队列问题;从生活中,可以抽象出队列的概念,队列就是一个能够实现“先进先出”的存储结构。队列分为链式队列和静态队列;静态队列一般用数组来实现,但此时的队列必须是循环队列,否则会造成巨大的内存浪费;链式队列是用链表来实现队列的。

#ifndef SQQUEUE_H_INCLUDED
#define SQQUEUE_H_INCLUDED /* 防止重复包含 */ 

//////////////////////////////////////////
//包含头文件
#include <stdlib.h>
#include "ds.h" // OK, Status 等定义 

//数据元素的类型(缺省使用int型)
#ifndef ElemType
#define ElemType int
#define USE_DEFAULT_ELEMTYPE /* 使用缺省类型的标志 */
#endif //ElemType 

//////////////////////////////////////////
//循环队列的存储结构 

#define MAXQSIZE 500/* 循环队列的最大容量 */
typedef struct {
  /* TODO (#1#): 这里完成循环队列的类型定义 */
  ElemType *base;
  int front;
  int rear;
  //....................................
} SqQueue; 

//////////////////////////////////////////
//循环队列的基本操作 

//构造一个空队列Q
Status InitQueue(SqQueue &Q)
{
  /* TODO (#2#): 构造空队列 */
  Q.base=(ElemType*)malloc(MAXQSIZE *sizeof(ElemType));
  if(!Q.base)exit(OVERFLOW);
  QQ.front=Q.rear =0;
  return OK; //TODO: 替换这行代码,以下同
  //....................................
} 

//销毁队列Q
// 前提:队列Q已存在
Status DestroyQueue(SqQueue &Q)
{
  /* TODO (#3#): 销毁队列 */
  free(Q.base);
  Q.base=NULL;
  Q.front=0;
  Q.rear=0;
  return OK;
  //....................................
} 

//将队列Q清为空队列
// 前提:队列Q已存在
Status ClearQueue(SqQueue &Q)
{
  /* TODO (#4#): 清空队列 */
  Q.base=0;
  Q.rear=0;
  return OK;
  //....................................
} 

//若队列Q为空,则返回TRUE,否则FALSE
// 前提:队列Q已存在
Status QueueEmpty(SqQueue Q)
{
  /* TODO (#5#): 判断队列是否为空 */
  if(Q.front==Q.rear)
    return OK;
  else
    return ERROR;
  //....................................
} 

//返回队列Q的元素个数,即队列长度
// 前提:队列Q已存在
int QueueLength(SqQueue Q)
{
  /* TODO (#6#): 返回队列长度 */
  return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
  //....................................
} 

//取队列Q头元素用e返回
// 前提:队列Q存在且非空
Status GetHead(SqQueue Q,ElemType &e)
{
  /* TODO (#7#): 取队头元素存入e */
  if(Q.rear==Q.front)
    return ERROR;
  e=Q.base[Q.front];
  //e=*(Q.base+Q.front);
  return OK;//返回操作状态(成功:OK,失败:ERROR)
  //....................................
} 

//插入元素e作为队列Q的新的队尾元素
// 前提:队列Q存在且未满
Status EnQueue(SqQueue &Q, ElemType e)
{
  /* TODO (#8#): 元素e入队列 */
  if((Q.rear+1)%MAXQSIZE==Q.front)
    return ERROR;
  //e=*(Q.base +Q.rear);
  Q.base[Q.rear]=e;
  Q.rear=(Q.rear+1)%MAXQSIZE;
  return OK;//返回操作状态(成功:OK,失败:ERROR)
  //....................................
} 

//删除队列Q的队头元素,并用e返回
// 前提:队列Q存在且非空
Status DeQueue(SqQueue &Q, ElemType e)
{
  /* TODO (#9#): 出队列存入e */
  if(Q.front==Q.rear)
    return ERROR;
  //e=*(Q.base+Q.front);
  e=Q.base[Q.front];
  Q.front=(Q.front+1)%MAXQSIZE;
  return OK;//返回操作状态(成功:OK,失败:ERROR)
  //....................................
} 

////////////////////////////////////////// 

//TODO: 定义好 SqQueue 类型后使用 QueueView 函数
/****** //TODO: 删除此行以便使用QueueView()
#include <stdio.h>
//查看队列状态(调试用)
void QueueView(SqQueue Q)
{
  extern void PrintElem(ElemType e);//打印数据用
  int i=0;
  if(Q.front<0||Q.front>=MAXQSIZE||Q.rear<0||Q.rear>=MAXQSIZE){
    printf("队列未初始化\n");
    return ;
  }
  printf("---Queue View---\n");
  printf("front=%d , rear=%d\n", Q.front, Q.rear);
  if(Q.rear>=Q.front) {
    printf(".....  ......\n");
    for(i=Q.front; i<Q.rear; i++) {
      printf("%5d\t", i);
      PrintElem(Q.base[i]);
      printf("\n");
    }
    if(i<MAXQSIZE) printf(".....  ......\n");
  } else {
    for(i=0; i<Q.rear; i++) {
      printf("%5d\t", i);
      PrintElem(Q.base[i]);
      printf("\n");
    }
    printf(".....  ......\n");
    for(i=Q.front; i<MAXQSIZE; i++) {
      printf("%5d\t", i);
      PrintElem(Q.base[i]);
      printf("\n");
    }
  }
  printf("--- view end ---\n");
}
******/ //TODO: 删除此行以便使用QueueView() 

//取消ElemType的默认定义,以免影响其它部分
#ifdef USE_DEFAULT_ELEMTYPE
#undef ElemType
#undef USE_EFAULT_ELEMTYPE
#endif 

#endif //SQQUEUE_H_INCLUDED 

#include <stdio.h>
#include <stdlib.h>
#include "sqqueue.h" 

//初始化系统 

void Finalize(SqQueue &q);  

////////////////////////////////////////////
//主程序
int main()
{
  SqQueue q; //循环队列
  int x; 

  //系统初始化
  InitQueue(q);
  printf("数据元素进队列,以0结束");
  scanf("%d",&x);
  while(x!=0){
   EnQueue(q,x);
   scanf("%d",&x);
  }
  printf("\n队列元素的个数"); 

  printf("%d",QueueLength(q)); 

  printf("\n头元素是:");
  if(!QueueEmpty(q)){
   if(GetHead(q,x)==OK)
   printf("%d",x);
  } 

  printf("\n出队列,先进先出");
   if( DeQueue(q,x)==OK)
     printf("%d",x);
  printf("\n此时的对头是:");
  if(!QueueEmpty(q)){
   if(GetHead(q,x)==OK)
   printf("%d\n",x);
  } 

}

实现的效果:

以上所述就是本文的全部内容了,希望大家能够理解。

(0)

相关推荐

  • java数据结构与算法之双向循环队列的数组实现方法

    本文实例讲述了java数据结构与算法之双向循环队列的数组实现方法.分享给大家供大家参考,具体如下: 需要说明的是此算法我并没有测试过,这里给出的相当于伪代码的算法思想,所以只能用来作为参考! package source; public class Deque { private int maxSize; private int left; private int right; private int nItems; private long[] myDeque; //constructor p

  • javascript中利用数组实现的循环队列代码

    //循环队列 function CircleQueue(size){ this.initQueue(size); } CircleQueue.prototype = { //初始化队列 initQueue : function(size){ this.size = size; this.list = new Array(); this.capacity = size + 1; this.head = 0; this.tail = 0; }, //压入队列 enterQueue : functio

  • C语言循环队列的表示与实现实例详解

    1.概述: C语言的队列(queue),是先进先出(FIFO, First-In-First-Out)的线性表数据结构.在具体应用中通常用链表或者数组来实现.队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作. 循环队列可以更简单的防止伪溢出的发生,但是队列大小是固定的. 2.实例代码: /* 队列的顺序存储结构(循环队列) */ #define MAX_QSIZE 5 /* 最大队列长度+1 */ typedef struct { QElemType *base

  • 使用C语言来解决循环队列问题的方法

    题目描述: 大家都知道数据结构里面有一个结构叫做循环队列.顾名思义,这是一个队列,并且是循环的.但是现在,淘气的囧哥给这个循环队列加上了一些规矩,其中有5条指令: (1) Push K, 让元素K进队列. (2) Pop,对头元素出队列. (3) Query K,查找队列中第K个元素,注意K的合法性. (4) Isempty,判断队列是否为空. (5) Isfull,判断队列是否已满. 现在有N行指令,并且告诉你队列大小是M. 输入: 第一行包含两个整数N和M.1<=N,M<=100000.

  • 循环队列详解及队列的顺序表示和实现

    循环队列--队列的顺序表示和实现 前面分析顺序队的时候,我们知道,顺序队存在"假溢出"的问题,这个问题有时会造成很大的内存浪费,循环队列就是为了解决这个问题而提出地一个很巧妙的办法.循环队列和顺序队列的主要区别在于:循环队列将顺序队列臆造成一个环状空间.在操作上这种异同体现在: 相同点: 在顺序队列和循环队列中,进行出队.入队操作时,队首.队尾指针都要加 1 ,朝前移动. 不同点: 1. 在循环队列中当队首.队尾指针指向向量上界(MAX_QUEUE_SIZE-1) 时,其加1 操作的结

  • php基于双向循环队列实现历史记录的前进后退等功能

    本文实例讲述了php基于双向循环队列实现历史记录的前进后退等功能.分享给大家供大家参考.具体如下: 为实现一个记录操作历史的功能 1. 和撤销,反撤销功能类似的一个功能.(实现操作的前进后退) 2. 和discuz论坛登录后查看帖子(可以前进后退查看过的帖子,还有帖子查看历史记录) 3. 逻辑和windows资源管理器地址栏前进后退功能一样. 根据这种需要,实现了一个数据结构.写了一个通用的类,暂叫历史记录类吧. [原理和时钟类似.实例化对象时可以构造长度为N(可以根据需要定长度)个节点的环]

  • JavaScript队列、优先队列与循环队列

    队列是一种遵从先进先出(FIFO)原则的有序集合 队列在尾部添加新元素,从顶部移除元素 队列的理解 队列在我们生活中最常见的场景就是排队了 队列这个名字也已经很通俗易懂了 和栈很像,这不过队列是先入先出的数据结构 队列的前面是队头 队列的后面是队尾 出队从队头出 入队从队尾入 队列的创建 和栈类似,这里我就不就不啰嗦了 同样需要实现一些功能 这里我类比生活中的排队上厕所 向队列中添加元素(进入排队的队伍中) 移除队头元素(队伍最前面的人出队进入厕所) 查看队头元素(查看队伍最前面的人) 判断队列

  • 详解数据结构C语言实现之循环队列

    本文讲的是循环队列,首先我们必须明白下面几个问题 循环队列的基础知识 1.循环队列需要几个参数来确定 循环队列需要2个参数,front和rear 2.循环队列各个参数的含义 (1)队列初始化时,front和rear值都为零: (2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置: (3)当队列为空时,front与rear的值相等,但不一定为零: 3.循环队列入队的伪算法 (1)把值存在rear所在的位置: (2)rear=(rear+1)%maxsize

  • C++循环队列实现模型

    本文实例讲述了C++循环队列实现模型.分享给大家供大家参考.具体分析如下: 前段时间在知乎上看到这样一个小题目: 用基本类型实现一队列,队列要求size是预先定义好的的.而且要求不可以使用语言自带的api,如C++的STL.普通的实现很简单,但是现在要求要尽可能的时间和空间复杂度的优化,要和语言自带的api比较时间和空间.这个队列还要支持如下的操作: constructor: 初始化队列 enqueue:入队 dequeue:出队 队列是一种基本的数据结构,在平常的应用中十分广泛,多数情况队列都

  • Java用数组实现循环队列的示例

    复习了下数据结构,用Java的数组实现一下循环队列. 队列的类 //循环队列 class CirQueue{ private int QueueSize; private int front; private int rear; private int[] queueList ; public CirQueue(int QueueSize){ this.QueueSize = QueueSize; queueList = new int[QueueSize]; front = 0; rear =

  • Java数据结构之循环队列简单定义与用法示例

    本文实例讲述了Java数据结构之循环队列简单定义与用法.分享给大家供大家参考,具体如下: 一.概述: 1.原理: 与普通队列的区别在于循环队列添加数据时,如果其有效数据end == maxSize - 1(最大空间)的话,end指针又移动到-1的位置 删除数据时,如果head== maxSize时 head指针移动到0的位置 2.示例图: 二.实现代码: package com.java.queue; /** * @描述 对列 * @项目名称 Java_DataStruct * @包名 com.

  • 如何实现循环队列

    生活中有很多队列的影子,比如打饭排队,买火车票排队问题等,可以说与时间相关的问题,一般都会涉及到队列问题:从生活中,可以抽象出队列的概念,队列就是一个能够实现"先进先出"的存储结构.队列分为链式队列和静态队列:静态队列一般用数组来实现,但此时的队列必须是循环队列,否则会造成巨大的内存浪费:链式队列是用链表来实现队列的. #ifndef SQQUEUE_H_INCLUDED #define SQQUEUE_H_INCLUDED /* 防止重复包含 */ /////////////////

  • JavaScript数据结构之优先队列与循环队列实例详解

    本文实例讲述了JavaScript数据结构之优先队列与循环队列.分享给大家供大家参考,具体如下: 优先队列 实现一个优先队列:设置优先级,然后在正确的位置添加元素. 我们这里实现的是最小优先队列,优先级的值小(优先级高)的元素被放置在队列前面. //创建一个类来表示优先队列 function Priorityqueue(){ var items=[];//保存队列里的元素 function QueueEle(e,p){//元素节点,有两个属性 this.element=e;//值 this.pr

随机推荐