同步操作将从 arrco/jh_queue 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
jh_queue是一个先进先出(FIFO)的队列(queue)。支持所有队列的基本功能,支持任意数据结构,本身没有内存的申请与释放,队列的空间由外部提供。jh_queue也是一个受限的双端队列,队尾支持先进后出(FILO),可以从队尾弹出数据,变成一个栈(stack)。
只需要包含jh_queue.c和jh_queue.h两个文件即可使用。
提供以下接口用于队列的使用:
/*判断队列是否为空*/
int jh_queue_is_empty(jh_queue_t* queue);
/*判断队列是否已满*/
int jh_queue_is_full(jh_queue_t* queue);
/*获取队列的数据数量*/
size_t jh_queue_count(jh_queue_t* queue);
/*数据入队*/
int jh_queue_push(jh_queue_t* queue, void* item);
/*数据出队*/
int jh_queue_pop(jh_queue_t* queue, void* item);
/*队尾数据出队*/
int jh_queue_pop_tail(jh_queue_t* queue, void* item);
/*查看队首的数据*/
int jh_queue_peek(jh_queue_t* queue, void* item);
/*查看队首的数据*/
int jh_queue_peek_head(jh_queue_t* queue, void* item);
/*查看队尾的数据*/
int jh_queue_peek_tail(jh_queue_t* queue, void* item);
/*清空队列*/
int jh_queue_clear(jh_queue_t* queue);
/*队列初始化*/
int jh_queue_init(jh_queue_t* queue, void* base, size_t num, size_t size);
另外还提供两个宏接口用于数据迭代:
/*队列数据迭代*/
JH_QUEUE_ITER(jh_queue_t* queue, void* item)
/*队列数据反向迭代*/
JH_QUEUE_ITER_REVERSE(jh_queue_t* queue, void* item)
调用接口jh_queue_init
初始化队列。
/*队列初始化*/
int jh_queue_init(jh_queue_t* queue, void* base, size_t num, size_t size);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列句柄,需要定义一个类型为jh_queue_t的参数 |
base | 指向用于队列的数组 |
num | 数组中能存放的数据项数量 |
size | 数组中每个数据项的大小 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
使用示例:
//定义数据结构和用于存放数据的数组
jh_queue_t queue;
int buf[10];
//队列初始化
jh_queue_init(&queue, buf, 10, sizeof(int));
注意:初始化时传入值num
,但实际可用于入队的数据数量为num - 1
。例如上述的示例,定义用于存放数据的数组长度为10,但实际可以用于入队的数据数量为9。
调用接口jh_queue_push
将数据入队。
/*数据入队*/
int jh_queue_push(jh_queue_t* queue, void* item);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 要入队的数据项 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口jh_queue_pop
将数据出队。
/*数据出队*/
int jh_queue_pop(jh_queue_t* queue, void* item);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 要出队的数据项 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口jh_queue_pop_tail
将队尾数据出队。
/*队尾数据出队*/
int jh_queue_pop_tail(jh_queue_t* queue, void* item);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 要出队的数据项 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口jh_queue_peek
查看队首的数据。
/*查看队首的数据*/
int jh_queue_peek(jh_queue_t* queue, void* item);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 队首的数据项 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口jh_queue_peek_tail
查看队尾的数据。
/*查看队尾的数据*/
int jh_queue_peek_tail(jh_queue_t* queue, void* item);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 队尾的数据项 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口jh_queue_count
查看队列中已有的数据数量。
/*获取队列的数据数量*/
size_t jh_queue_count(jh_queue_t* queue);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
函数返回值:
返回值 | 含义 |
---|---|
>=0 | 队列的数据数量 |
调用接口jh_queue_is_full
判断队列是否已满。
/*判断队列是否已满*/
int jh_queue_is_full(jh_queue_t* queue);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
函数返回值:
返回值 | 含义 |
---|---|
1 | 队列已满 |
0 | 队列未满 |
-1 | 失败 |
注意:队列可用于入队的最大数据数量为num - 1
,num
指的是在初始化时调用接口jh_queue_init
时设置的num
。
调用接口jh_queue_is_empty
判断队列是否为空。
/*判断队列是否为空*/
int jh_queue_is_empty(jh_queue_t* queue);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
函数返回值:
返回值 | 含义 |
---|---|
1 | 队列为空 |
0 | 队列不为空 |
-1 | 失败 |
调用接口jh_queue_clear
清空队列内的数据。
/*清空队列*/
int jh_queue_clear(jh_queue_t* queue);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
调用接口JH_QUEUE_ITER
或者JH_QUEUE_ITER_REVERSE
进行数据迭代。
/*队列数据迭代*/
JH_QUEUE_ITER(jh_queue_t* queue, void* item)
/*队列数据反向迭代*/
JH_QUEUE_ITER_REVERSE(jh_queue_t* queue, void* item)
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 数据项 |
使用示例,打印出当前队列中的所有数据:
//从队首到队尾的顺序遍历
JH_QUEUE_ITER(&queue, &val) {
printf("val : %d\n", val);
}
//从队尾到队首的顺序遍历
JH_QUEUE_ITER_REVERSE(&queue, &val) {
printf("val : %d\n", val);
}
这是一个特殊接口,正常队列是没有这个功能的。可以获取队列中任意位置的数据,或者从任意位置开始,指定数量的连续数据。如果指定的位置超出队列范围,则获取失败返回 0 ;如果指定数量超过实际的数据长度,则返回实际长度的数据。
调用接口jh_queue_get_data
使用。
/*获取队列指定位置的指定数量数据*/
int jh_queue_get_data(jh_queue_t* queue, void* item, size_t start, size_t num);
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
item | 获取的数据项 |
start | 指定的起始位置 |
num | 指定的数量 |
函数返回值:
返回值 | 含义 |
---|---|
>=0 | 成功获取的数据数量 |
-1 | 失败 |
调用接口jh_queue_sort
对队列内的数据进行排序。
/*队列数据排序*/
int jh_queue_sort(jh_queue_t* queue, int (*compare)(const void*, const void*));
函数参数含义:
参数 | 含义 |
---|---|
queue | 队列 |
compare | 指向用于比较两个数据项的函数指针 |
函数返回值:
返回值 | 含义 |
---|---|
0 | 成功 |
-1 | 失败 |
需要定义一个用于比较两个数据项的compare函数。这个函数的实现方式影响数据会如何排序。
函数的类型为int (*compare)(const void* p1, const void* p2)
。
函数返回值:
返回值 | 含义 |
---|---|
小于0 | p1指向的数据项排在在p2指向的数据项之前 |
大于0 | p1指向的数据项排在在p2指向的数据项之后 |
等于0 | p1指向的数据项与p2指向的数据项相同 |
使用示例,假设保存的数据类型为int,按从小到大的方式排序:
int compare(const void * p1, const void * p2)
{
return ( *(int*)p1 - *(int*)p2 );
}
队列的基础用法:
int main(int argc, char* argv[])
{
//定义数据结构和用于存放数据的数组
jh_queue_t queue;
int buf[10];
//队列初始化
jh_queue_init(&queue, buf, 10, sizeof(int));
//定义要用于传入的数据
int items[] = {81, 13, 16, 38, 49, 67};
int i, val;
//数据入队
printf("push :\n");
for(i = 0; i < sizeof(items)/sizeof(int); i++) {
if(!jh_queue_push(&queue, &items[i]))
printf("%d ", items[i]);
}
printf("\n");
//查看当前的状态
printf("\nsize : %d empty : %d full : %d\n", jh_queue_count(&queue), jh_queue_is_empty(&queue), jh_queue_is_full(&queue));
//查看队首的数据
jh_queue_peek(&queue, &val);
printf("peek %d\n", val);
//查看队尾的数据
jh_queue_peek_tail(&queue, &val);
printf("peek tail %d\n", val);
//数据出队
printf("\npop:\n");
for(i = 0; i < sizeof(items)/sizeof(int); i++) {
if(!jh_queue_pop(&queue, &val))
printf("%d ", val);
}
printf("\n");
//查看当前的状态
printf("\nsize : %d empty : %d full : %d\n", jh_queue_count(&queue), jh_queue_is_empty(&queue), jh_queue_is_full(&queue));
//数据入队
printf("\npush :\n");
for(i = 0; i < sizeof(items)/sizeof(int); i++) {
if(!jh_queue_push(&queue, &items[i]))
printf("%d ", items[i]);
}
printf("\n");
//可以查看当前所有数据,从队首到队尾的顺序遍历
printf("\niter:\n");
JH_QUEUE_ITER(&queue, &val) {
printf("%d ", val);
}
printf("\n");
//可以查看当前所有数据,从队尾到队首的顺序遍历
printf("\niter reverse:\n");
JH_QUEUE_ITER_REVERSE(&queue, &val) {
printf("%d ", val);
}
printf("\n");
//将队尾数据出队,可以作为栈使用
printf("\npop tail:\n");
for(i = 0; i < sizeof(items)/sizeof(int); i++) {
if(!jh_queue_pop_tail(&queue, &val))
printf("%d ", val);
}
printf("\n");
//查看当前的状态
printf("\nsize : %d empty : %d full : %d\n", jh_queue_count(&queue), jh_queue_is_empty(&queue), jh_queue_is_full(&queue));
//数据入队
printf("\npush :\n");
for(i = 0; i < sizeof(items)/sizeof(int); i++) {
if(!jh_queue_push(&queue, &items[i]))
printf("%d ", items[i]);
}
printf("\n");
//清空队列
printf("\nclear\n");
jh_queue_clear(&queue);
//查看当前的状态
printf("\nsize : %d empty : %d full : %d\n", jh_queue_count(&queue), jh_queue_is_empty(&queue), jh_queue_is_full(&queue));
return 0;
}
运行结果如下:
push :
81 13 16 38 49 67
size : 6 empty : 0 full : 0
peek 81
peek tail 67
pop:
81 13 16 38 49 67
size : 0 empty : 1 full : 0
push :
81 13 16 38 49 67
iter:
81 13 16 38 49 67
iter reverse:
67 49 38 16 13 81
pop tail:
67 49 38 16 13 81
size : 0 empty : 1 full : 0
push :
81 13 16 38 49 67
clear
size : 0 empty : 1 full : 0
MIT License
Copyright (c) 2022 Hong Jiahua
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。