数据结构详解:顺序队列的实现与应用
创作时间:
作者:
@小白创作中心
数据结构详解:顺序队列的实现与应用
引用
CSDN
1.
https://blog.csdn.net/Cym20231111/article/details/145787940
在讲解顺序队列之前,我们先来了解一下队列的基本概念。
队列的基本概念
队列,就像排队时的队列一样,是一种特殊的线性表。其特殊之处在于:只能在固定的两端进行操作。这种操作方式使得队列呈现出“先进先出”的逻辑特性。
在队列中,两端的操作被赋予了特定的名称:
- 队头:可以删除节点的一端
- 队尾:可以插入节点的一端
- 入队:将节点插入到队尾之后,函数名通常为
enQueue()
- 出队:将队列的头节点从队列中剔除,函数名通常为
outQueue()
- 取队头:取得队头的元素但不出队,函数名通常为
front()
顺序队列
队列可以采用顺序存储方式形成循环队列。循环队列通过更新队头和队尾的下标信息,可以循环利用整个队列空间,入队和出队操作时不需要移动队列中的数据。
循环队列图解:
为了区分循环队列中的满队(队列为满)和空队(队列为空),需要空出至少一个存储位置:
- 当
front
与rear
相等时,队列为空 - 当
rear
循环+1 与front
相等时,队列为满
管理循环队列除了需要一块连续的内存之外,还需要记录队列的总容量、当前队列的元素个数、当前队头、队尾元素位置,如果有多线程还需要配互斥锁和信号量等信息。
顺序循环队列的管理结构体设计
图解:
示例代码:
// 学生结构体
typedef struct student
{
int id; // 学生的学号
char name[128]; // 学生的姓名
}stu_t, *stu_p;
// 顺序循环队列管理结构体设计
typedef struct sequence_queue
{
stu_p data_p; // 顺序循环队列的内存的入口
int capacity; // 顺序循环队列的总容量
int front; // 顺序循环队列的队头的元素下标
int rear; // 顺序循环队列的队尾的元素下标
}sq_queue_t, *sq_queue_p;
初始化顺序循环队列
图解:
示例代码:
/**
* @brief 初始化顺序循环队列
* @note None
* @param cap_size:队列的容量
* @retval 成功:返回指向队列的内存的指针
* 失败:返回NULL
*/
sq_queue_p SEQUENCE_QUEUE_Init( int cap_size )
{
// 1、申请顺序队列的堆内存空间(申请堆区1)
sq_queue_p p = malloc( sizeof( sq_queue_t ) );
bzero( p, sizeof( sq_queue_t ) );
// 2、给该内存空间(堆区1)进行赋值操作
if ( p != NULL)
{
// 堆区1里面的堆区2的空间
p->data_p = malloc( sizeof( stu_t ) * cap_size );
if ( p->data_p == NULL )
{
free(p);
return NULL;
}
// 堆区1的特征遍历
p->capacity = cap_size;
p->front = 0;
p->rear = 0;
}
else
return NULL;
// 3、成功返回0
return p;
}
判断顺序循环队列是否为空
示例代码:
/**
* @brief 判断顺序循环队列是否为空
* @note None
* @param p:指向队列的管理结构体的指针
* @retval 如果队列为空: 返回true
* 队列为非空:返回false
*/
bool SEQUENCE_QUEUE_IfEmpty( sq_queue_p p )
{
return ( p->front == p->rear );
}
判断顺序循环队列是否为满
示例代码:
/**
* @brief 判断顺序循环队列是否为满
* @note None
* @param p:指向队列的管理结构体的指针
* @retval 如果队列为满: 返回true
* 队列为非满:返回false
*/
bool SEQUENCE_QUEUE_IfFull( sq_queue_p p )
{
return ( ( p->rear + 1 ) % ( p->capacity ) == p->front );
}
入队 --- 插入数据
示例代码:
/**
* @brief 入队
* @note None
* @param p: 指向顺序循环队列的管理结构体的指针
* data: 要赋值的数据
* @retval 成功: 返回0
* 失败: 返回非0
*/
int SEQUENCE_QUEUE_EnQueue( sq_queue_p p, stu_t data )
{
// 1、判断队列是否是满的
if ( SEQUENCE_QUEUE_IfFull(p) )
return -1;
// 2、在队列的队尾插入数据
p->data_p[ p->rear ].id = data.id;
strcpy( p->data_p[ p->rear ].name, data.name );
// 3、队尾标志+1
p->rear = ( p->rear+1 ) % ( p->capacity ); // 因为是循环队列,因此需要取余操作
// 4、成功返回
return 0;
}
出队 --- 删除数据
示例代码:
/**
* @brief 出队
* @note None
* @param p:指向顺序循环队列的管理结构体的指针
* @retval 成功:返回0
* 失败:返回非0
*/
int SEQUENCE_QUEUE_OutQueue( sq_queue_p p )
{
// 1、判断队列是否是空的
if ( SEQUENCE_QUEUE_IfEmpty(p) )
return -1;
// 2、在队列的队头删除数据
bzero( &p->data_p[ p->front ], sizeof( stu_t ) ); // 清空数据(这一步其实可以不用)
p->front = ( p->front+1 ) % ( p->capacity ); // 因为是循环队列,因此需要取余操作
// 3、成功返回
return 0;
}
获取队头的数据 --- 查询数据
示例代码:
/**
* @brief 获取队头的数据
* @note None
* @param p:指向顺序循环队列的管理结构体的指针
* @retval 成功:返回指向队列的队头的数据的指针
* 失败:NULL
*/
stu_p SEQUENCE_QUEUE_GetFrontData( sq_queue_p p )
{
// 1、判断队列是否是空的
if ( SEQUENCE_QUEUE_IfEmpty(p) )
return NULL;
// 2、将指针队头的数据的指针返回
return &( p->data_p[ p->front ] );
}
遍历整个队列
示例代码:
/**
* @brief 遍历整个队列
* @note None
* @param p:指向顺序循环队列的管理结构体的指针
* @retval 成功:返回0
* 失败:返回非0
*/
int SEQUENCE_QUEUE_ShowQueue( sq_queue_p p )
{
// 1、判断队列是否是空的
if ( SEQUENCE_QUEUE_IfEmpty(p) )
return -1;
// 2、遍历整个顺序队列
printf("================顺序队列里的数据===============\n\n");
for ( int i = p->front; i != p->rear; i++, i = i % ( p->capacity ) ) // 由于是循环队列,因此需要取余操作
{
printf("sq_queue[%d] = 学生的ID:%d, 学生的姓名:%s\n", i, p->data_p[i].id, p->data_p[i].name);
}
printf("==============================================\n\n");
// 3、成功返回0
return 0;
}
销毁队列
示例代码:
/**
* @brief 销毁队列
* @note None
* @param p:指向顺序循环队列的管理结构体的指针
* @retval None
*/
int SEQUENCE_QUEUE_UnInit( sq_queue_p p )
{
free( p->data_p );
free(p);
}
以上内容是关于顺序队列的详细讲解,包括其基本概念、实现方式以及相关操作的代码示例。通过这些内容,读者可以全面了解顺序队列的原理和应用。
热门推荐
小猪V5教你如何成为社区团购超级团长
什么是CUDA?CUDA基础知识介绍
美国多数行业工作时长回落至近三年低位
一起彩揭秘:彩票号码背后的秘密
解密彩票心理学:为什么觉得自己更容易中奖?
全球化背景下的跨文化沟通:挑战与应对
中西文化差异,如何影响你的英语学习?
跨国公司如何破解跨文化沟通难题?
GAN和VAE:AI合成照片的新纪元
从文物到“活物”,科技助力考古和文物保护“炫”起来
《追风筝的人》:一个关于背叛与救赎的故事
去香港能带多少现金?海关提醒:携带进出境现钞有限额
番茄小说改名攻略:让你的作品C位出道!
番茄小说改书名全攻略:从步骤到技巧,一文掌握!
番茄小说头条推荐:如何用精准语言吸粉?
双十一单身狗被催婚?长辈观念大揭秘!
费孝通视角下的长辈催婚现象解析
如何写出一份高分实习总结报告?
新媒体运营:让你的实习总结C位出道!
用WPS高效完成实习总结,提升职场竞争力
如何克服心理实习写作障碍?这份实用指南请收好!
到底谁的基因决定了孩子的智商和长相?遗传基因的科学结论来了
如何帮助孩子发现并利用自己的天赋和兴趣?家长必看!
如何理解和引导叛逆孩子,建立良好亲子关系的艺术探讨
儿童保健与疾病预防全攻略
心电图机原理及电路超详细讲解
酸枣仁汤:千年古方如何科学应对现代人失眠困扰?
自制酸枣仁汤,告别失眠烦恼!
张仲景秘方:酸枣仁汤助眠大揭秘
卧室和客厅如何正确摆放水晶能量塔