C语言数据结构算法基础之循环队列示例

 更新时间:2022年06月06日 10:20:02   作者:jiangwei0512  
这篇文章主要为大家介绍了C语言数据结构算法基础之循环队列,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

说明

循环队列是一种先进先出的,首尾相连的队列。

大致的结构如下图:

用数组来抽象的表示一下的话,如下图:

循环队列有两个指针指向数据,上图中的start和end就是那两个指针,它们指向相同的位置,表示的是空,即队列是空的。

随着数据的放入,队列一般有下面的两种形式:

需要注意第二种形式,从图上看end在start的前面了,但是因为循环关系,前后并不重要。

另外需要考虑的是队列满的情况:

但这种情况存在一个问题,即空队列和满队列没有办法区分了,end和start都指向了相同的位置。

为了解决这个问题,一个方法是空出一个位置不放数据,当end再加一个数据就等于start的时候就认为队列是满的:

这时实际的数据长度就会比分配的少1。

下面是队列中空和满的判断:

1. 队列为空时:end == start

2. 队列为满时:(end + 1) % size == start

这里的size是指分配的空间大小,而不是队列长度,队列的实际长度为(end - start + size) % size,最大长度是size-1

这也是因为要考虑循环的关系,所以要加上%size这个操作。

示例代码

1. 首先定义结构体:

//定义循环队列
typedef struct _LoopQueue {
	int data[8];		//存放数据
	int start;		//头指针
	int end;		//尾指针
} LoopQueue;

2. 定义各种算法:

#define TRUE	1
#define FALSE	0
#define SIZE	8
//初始化队列
int init(LoopQueue *lq) {
	lq->start = 0;
	lq->end = 0;
	return TRUE;
}
//判断队列是否为空
int isEmpty(LoopQueue *lq) {
	if (lq->start == lq->end) {
		return TRUE;
	}
	return FALSE;
}
//判断队列是否为满
int isFull(LoopQueue *lq) {
	if ((lq->end + 1) % SIZE == lq->start) {
		return TRUE;
	}
	return FALSE;
}
//获取队列的长度
int getLength(LoopQueue *lq) {
	return (lq->end - lq->start + SIZE) % SIZE;
}
//插入数据
int pushQueue(LoopQueue *lq, int data) {
	if(isFull(lq)) {
		printf("Queue is full.\n");
		return FALSE;
	}
	lq->data[lq->end] = data;
	lq->end = (lq->end + 1) % SIZE;
	return TRUE;
}
//弹出数据
int popQueue(LoopQueue *lq, int *data) {
	if (isEmpty(lq)) {
		printf("Queue is empty.\n");
		return FALSE;
	}
	*data = lq->data[lq->start];
	lq->start = (lq->start + 1) % SIZE;
	return TRUE;
}
//显示队列中的数据
void printQueue(LoopQueue *lq) {
	int index;
	int count;
	count = getLength(lq);
	if (0 == count) {
		printf("No data.\n");
		return;
	}
	for (index = 0; index < count; index++) {
		printf("%d ", lq->data[index]);
	}
	printf("\n");
	return;
}

3. 测试:

int main()
{
	int index;
	int num;
	//队列测试代码
	LoopQueue *lq = (LoopQueue *)malloc(sizeof(LoopQueue));
	init(lq);
	printQueue(lq);
	for (index = 0; index < SIZE; index ++) {	//注意这里要放8个数据,但是实际上只能放7个,所以最后一个会报错
		pushQueue(lq, index);
	}
	printQueue(lq);
	for (index = 0; index < SIZE; index ++) {	//同上,会打印一个错误
		if (popQueue(lq, &num)) {
			printf("%d\n", num);
		}
	}
	printQueue(lq);
	return 0;
}

4. 最后的结果:

以上就是C语言数据结构算法基础之循环队列的详细内容,更多关于C语言数据结构算法循环队列的资料请关注脚本之家其它相关文章!

相关文章

  • C语言中单链表的基本操作指南(增删改查)

    C语言中单链表的基本操作指南(增删改查)

    链表跟数组不同的是非连续存储结构,也就是说实现链表需要一个指针,每用完一个节点指针指向下一个节点,直至表尾,下面这篇文章主要给大家介绍了关于C语言中单链表的基本操作之增删改查的相关资料,需要的朋友可以参考下
    2021-09-09
  • C++实现栈与分析栈的知识点

    C++实现栈与分析栈的知识点

    这篇文章主要介绍了C++实现栈与分析栈的知识点,栈(stack)是计算机中常用的一种线性数据结构,经常有资料使用“操作受限”来形容栈,因为它的压入栈和弹出栈操作只能在栈顶进行,下文更多相关资料,需要的小伙伴可以参考一下
    2022-03-03
  • VC自定义消息响应函数postmessage用法示例

    VC自定义消息响应函数postmessage用法示例

    这篇文章主要介绍了VC自定义消息响应函数postmessage用法示例,并对比说明了postmessage与sendmessage的用法区别,需要的朋友可以参考下
    2014-10-10
  • 详解C++编程中断言static_assert的使用

    详解C++编程中断言static_assert的使用

    这篇文章主要介绍了C++编程中断言static_assert的使用,断言在debug时非常有用,是C++入门学习中的基础知识,需要的朋友可以参考下
    2016-01-01
  • c++作用域运算符用法(全局变量和局部变量)

    c++作用域运算符用法(全局变量和局部变量)

    这篇文章主要介绍了c++作用域运算符用法,需要的朋友可以参考下
    2014-04-04
  • Qt超时锁屏的实现示例

    Qt超时锁屏的实现示例

    本文主要介绍了Qt超时锁屏的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C++学校运动会管理系统的实现

    C++学校运动会管理系统的实现

    这篇文章主要为大家详细介绍了C++如何实现学校运动会管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • 详解C++异常处理三个重要组成部分

    详解C++异常处理三个重要组成部分

    这篇文章主要为大家介绍了C++异常处理的三个重要组成部分示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • C++  STL _ Vector使用及模拟实现

    C++  STL _ Vector使用及模拟实现

    这篇文章主要介绍了C++ STL_Vector使用及模拟实现,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • Qt使用事件与定时器实现字幕滚动效果

    Qt使用事件与定时器实现字幕滚动效果

    我们经常能够在外面看到那种滚动字幕,那么本文就拿Qt来做一个吧,本文将使用事件与定时器实现字幕滚动的效果,感兴趣的小伙伴可以了解一下
    2023-06-06

最新评论