C语言 循环队列的使用

循环队列的优势

相比普通的队列,能够有效节省内存的使用,无需再次分配内存

循环队列的实现源码

#include"stdio.h"
#include"stdlib.h"

//这是一个静态队列的例程
#define MAXSIZE 10   //队列的最大容量
typedef char ElemType;  //定义一个队列元素类型,这种编程思路很好,程序有扩展空间
//声明一个有关循环队列的数据块,注意每个元素的意义!
struct Queue
{
   ElemType *base;//数据类型头指针
   int front;  //队头(front)进行队列元素删除操作的数组指针索引,很巧妙!
   int rear;  //队尾(rear)进行队列元素插入操作的数组指针索引,很巧妙!
};

//创建队列或曰初始化队列
void Queue_Iinit(Queue * q)
{
 //   q= new Queue;
  q->base=(ElemType *)malloc(MAXSIZE*sizeof(ElemType));//
  if(!q->base)
  {
    printf("内存分配失败!\n");
	exit(1);
  }
  q->front=q->rear=0;
  //这一步很重要!将队头和队尾指针索引q->front,q->rea都赋值为0,即同时指向数组第一个元素

}
//入队操作,入队从队尾rear处开始
void InsertQueue(Queue * q,ElemType e)
{
  if((q->rear+1)%MAXSIZE==q->front)//先判断队列是否已满,因为入队从队尾rear处开始,所以先判断rear指针索引
/*
  表达式(q->rear+1)%MAXSIZE也叫取模运算,该表达式能确保(q->rear+1)%MAXSIZE的结果小于MAXSIZE!
  这样可以确保数组指针不越界。为什么要rear加1呢?腾出一个数据的空闲空间。
  这种算法很技巧!

  */
  {
     printf("队列已满!\n");
     return;
  
  }
  q->base[q->rear]=e;//
  q->rear=((q->rear+1)%MAXSIZE);//这一步既实现了指针前移同时还实现了指针不越界!技巧!

}
//出队操作,出队是从队头front处开始
void DeleteQueue(Queue * q,ElemType *e)
{
    if(q->front==q->rear)//已空,说明队列元素已经删除完毕
    {
	  printf("老大,队列已空!\n");
	  return;
	}
 //   *(e++)=q->base[q->front];//完成此步还不够!还需要指针索引移位!注意赋值方法!
	*e=q->base[q->front];//完成此步还不够!还需要指针索引移位!注意赋值方法!
    q->front=(q->front+1)%MAXSIZE; //指针指向下一个空闲空间,确保不越界
    
  
	  
}

//判断队列是否为空
bool EmptyQueue(Queue * q)  
{  
    if(q->front==q->rear)    //判断是否为空  
	{  
        printf("队列已空!\n");
		return true; 
	}
    else  
        return false;  
}  
//判断队列是否为满
bool FullQueue(Queue * q) 
{  
   if((q->rear+1)%MAXSIZE==q->front)   //判断循环链表是否满,留一个预留空间不用  
   {
	  printf("队列已满!\n");
	   return true; 
   } 
    else  
        return false;  
}  
/*********************************************** 
输出每一个元素
************************************************/  
void TraverseQueue(Queue * q)  
{  
    int i=q->front;  
    printf("队中的元素是:\n");  
    while( (i%MAXSIZE)!=q->rear )  //注意,这里没有加1,打印每一个元素
    {  
        printf("%c\n ",q->base[i]);  
        i++;  
    }  
    printf("\n");  

}  
void main()
{
  
    Queue q;
	char c;
   
    Queue_Iinit(&q);

	printf("请输入循环队列元素,以#作为结束符\n");
 
	scanf("%c",&c);//注意!本句表示一次输入一个字符
  
	InsertQueue(&q,c);
    
/*
  注意:比如输入“1110010#”再按下回车键,字符串“1110010#”就以一次一个字符的顺序输入到PC键盘缓冲区即入栈;
  出栈时是以“后进先出”的顺序出栈,刚好最后入栈的字符就是二进制的最低位。对于栈的操作一定要注意入栈出栈顺序	
*/ 

	while(c!='#')
	{

   	  scanf("%c",&c);//这里为什么还要此句呢?因为scanf()一次只能输入一个字符,所以必须循环输入
      InsertQueue(&q,c);
	}
	getchar();//改变键盘输入缓存指针,即将回车键读出来,这样可以避免“\r”字符(回车键)输出

	TraverseQueue(&q);
    printf("开始出队命令!\n"); 

 	
   
    while(1)
	{	
    
		DeleteQueue(&q,&c);

	    printf("出队:%c\n ",c);
		if( EmptyQueue( &q))
			break;
	 
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的小熊~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值