`

静态循环队列的相关操作及详解

 
阅读更多

循环队列

队列通常分为两类:一是动态链式队列(其核心思想为链表,只是少了链表的一些功能),二是静态(顺序)队列(其核心是用数组实现,准确一点讲是由向量空间来实现,向量空间好比是开辟的一块内存,由我们的指针来指向其地址)。顺序队列实际上是运算受限的顺序表,由于队列的队头和队尾的位置是变化的,通常设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0。由于入队和出队操作中,头尾指针只增加不减小,致使被删元素的空间永远无法重新利用。当队列中实际的元素个数远远小于向量空间的规模时,也可能由于尾指针已超越向量空间的上界而不能做入队操作。这种“假上溢”现象常常造成内存资源的浪费,这时就产生了循环队列(首尾相接)。循环队列克服“假上溢”现象的方法是:将向量空间想象成一个首尾相连的圆环,将循环队列存放在其中。循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。针对这样情况,有两种解决方法:一是少用一个元素的空间。约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空),;二是使用一个计数器记录队列中元素的总数(即队列长度)。我们通常使用第一种方法,也就是少用一个元素的空间。

循环队列相关操作思路

1.初始化: 造数组,设其数组长度为n=5(规定当数组中有n-1个元素时已满),初始化队头队尾值都为0;

2.入队

先判断队列是否已满:(队尾+1)%数组长度==队头 是否成立?即队尾和队头紧挨着;

为队尾的下一个元素赋值;

让队尾加1;

3.出队

先判断队列是否为空:若队首和队尾相等,则该队列一定为空(但队首和队尾值不一定为0,这个由初始化、入队、出队等相关操作后的数组下标位置决定)

保存一份要出队的值;

让队头加1;

实例说明

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Queue
{
	int *pBase;//pBase指向数组名(通常静态队列都使用循环队列)
	int front;//数组下标,这里规定从零开始
	int rear;
}QUEUE;//QUEUE代表了struct Queue
void init(QUEUE *);//初始化
bool en_queue(QUEUE *,int);//入队
bool full_queue(QUEUE *);//判断循环队列是否已满
bool del_queue(QUEUE *,int *);//出队
bool empty_queue(QUEUE *);//判断循环队列是否为空
bool traverse_queue(QUEUE *);//遍历输出
int length(QUEUE *);//求循环队列的长度

int main()
{
	QUEUE Q;
	int val;
	init(&Q);
	en_queue(&Q,1);
	en_queue(&Q,2);
	en_queue(&Q,3);
	en_queue(&Q,4);
    traverse_queue(&Q);      
    if(del_queue(&Q,&val))
		printf("出队成功,出队元素的值为:%d\n",val);
	else
		printf("出队失败!");
	traverse_queue(&Q); 
    printf("队列的长度为:%d\n",length(&Q));
	
	return 0;
}
void init(QUEUE *pQ)
{
	pQ->pBase=(int *)malloc(sizeof(int)*5);//造数组,设其数组长度为n=5(规定当数组中有n-1个元素时已满),初始化时使Queue的成员front、rear的值都为0
	if(NULL==pQ->pBase)
	{
		printf("动态内存分配失败!\n");
		exit(-1);
	}
	pQ->front=0;
	pQ->rear=0;
}
bool full_queue(QUEUE *pQ)
{
	if((pQ->rear+1)%5==pQ->front)
		return true;
	else
		return false;
}
bool en_queue(QUEUE *pQ,int val)
{
	if(full_queue(pQ))
	{
		printf("队列已满,入队失败!\n");
		return false;
	}
    pQ->pBase[pQ->rear]=val;
	pQ->rear=(pQ->rear+1)%5;//队尾加1
	return true;
}
bool del_queue(QUEUE *pQ,int *pVal)
{
	if(empty_queue(pQ))
		return false;
    *pVal=pQ->pBase[pQ->front];
	pQ->front=(pQ->front+1)%5;
	return true;
}
bool empty_queue(QUEUE *pQ)
{
	if(pQ->rear==pQ->front)//因为队列不为空时,rear和front肯定不相等
		return true;
	else
		return false;
}
bool traverse_queue(QUEUE *pQ)
{
	int i=pQ->front;
	if(empty_queue(pQ))
	{
		printf("队列为空,遍历失败!\n");
		return false;
	}
	printf("队列元素有:");
	while(i!=pQ->rear)
	{
		printf("%d  ",pQ->pBase[i]);
		i=(i+1)%5;				
	}
	printf("\n");
	return true;
}
int length(QUEUE *pQ)
{
	int len=0;
	int i=pQ->front;;
	if(empty_queue(pQ))
        return 0;//队列为空,长度为0
	while(i!=pQ->rear)
	{
		i=(i+1)%5;
		++len;
	}
	return len;
}


注意

1.指针只在入队和出队时移动,其它情况下不能移动。

2.队列初始化:front和rear的值都是零;

3.队列非空:front代表的是队列的第一个元素,rear代表的是队列的最后一个有效元素的下一个元素。

4.顺序队列和循环队列最直观的区别就是:循环队列首尾相连形成一个圆环,而顺序队列不成环状(通常会造成内存资源的浪费)。

5.队列的应用非常广泛,所有与时间有关的操作都可以用到队列。

结束语

有关循环链表的相关操作及伪算法的分析就写到这,明天开始学习递归。

分享到:
评论

相关推荐

    最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料

    for 循环及作业要求 第2周 本节鸡汤 模块初识 pyc是什么 python数据类型 bytes数据类型 列表的使用 元组与购物车程序练习 购物车程序练习实例 字符串常用操作 字典的使用 三级菜单实例 本周作业-购物车优化 第3周...

    python入门到高级全栈工程师培训 第3期 附课件代码

    03 用户增删该查及组相关操作 04 对文件的权限管理 05 对目录的权限管理 06 权限管理补充 07 属主属组及基于数字的权限管理 第5章 01 上节课复习 02 文件合并与文件归档 03 文件归档与两种压缩方式 04 vim编辑器 ...

    Absolute C++中文版(原书第2版)-完美的C++教程,文档中还包含英文版

    4.1.3 引用调用机制详解 95 4.1.4 常量引用参数 97 4.1.5 混合参数列表 99 4.2 重载与默认实参 104 4.2.1 重载简介 104 4.2.2 分辨重载的准则 107 4.2.3 默认实参 109 4.3 测试及调试函数 111 4.3.1 assert...

    宋劲彬的嵌入式C语言一站式编程

    1.2. socket地址的数据类型及相关函数 2. 基于TCP协议的网络程序 2.1. 最简单的TCP网络程序 2.2. 错误处理与读写控制 2.3. 把client改为交互式输入 2.4. 使用fork并发处理多个client的请求 2.5. setsockopt 2.6. ...

    windows 程序设计中文版

    3.1.7 消息循环 3.1.8 窗口过程 3.1.9 消息的处理 3.1.10 声音文件的播放 3.1.11 WM_PAINT消息 3.1.12 WM_DESTROY消息 3.2 Windows编程中的若干难点 3.2.1 究竟是谁调用谁 3.2.2 队列消息和非队列消息 3.2.3 ...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【Redis】redis五种常见的数据类型详解 123 String字符串类型 124 List列表类型 126 Set集合类型 128 Hash散列类型 130 Redis的有序集合ZSet数据类型 131 【Redis】Redis的存储结构,或者说如何工作的,与mysql的...

    Java开发技术大全 电子版

    11.2.3优先队列(PriorityQueue)使用示例340 11.2.4哈希集合(HashSet)使用示例343 11.2.5哈希映射类(HashMap)使用示例347 11.2.6有序树(TreeSet)使用示例349 11.2.7有序树映射类(TreeMap)使用示例353 ...

    Linux c编程一站式学习

    8.1. 数组的基本操作............................................84 8.2. 数组应用实例:统计随机数..................................86 8.3. 数组应用实例:直方图......................................89 ...

Global site tag (gtag.js) - Google Analytics