一、队列
1、queue.c内容
#include "02queue.h" //队列的初始化函数 void queue_init(queue *p_queue/*指向调用函数提供的代表队列的结构体存储区*/) { //初始化要保证队列里没有数字,也就是 //head和tail成员变量必须相等 p_queue->head = 0; p_queue->tail = 0; } //队列的清理函数 void queue_deinit(queue *p_queue) { //清理函数需要把队列里的数字都删除 p_queue->head = 0; p_queue->tail = 0; } //获得队列里数字个数的函数 int /*表示得到的数字个数*/queue_size(const queue *p_queue) { return p_queue->tail - p_queue->head; } //判断队列是否空的函数 int /*返回值为真表示队列空,否则不空*/queue_empty(const queue *p_queue) { return p_queue->head == p_queue->tail; } //判断队列是否满的函数 int /*返回值为真表示队列满,否则不满*/queue_full(const queue *p_queue) { //只要最后一个存储区被使用过 //就表示队列满了 return p_queue->tail >= SIZE; } //向队列里加入数字的函数 int /*返回值为真表示成功加入,否则加入不成功*/queue_push(queue *p_queue, int val/*要加入的数字*/) { if (p_queue->tail >= SIZE) { //如果队列已经满了就不能在加入数字了 return 0; } p_queue->buf[p_queue->tail] = val; //把新数字放在数组里以tail做下标的存储区里 p_queue->tail++; //tail向后移动一步 return 1; } //从队列里获得数字的函数(同时删除数字) int /*返回值为真表示获得数字成功,否则失败*/queue_pop(queue *p_queue, int *p_val/*用来向调用函数传递数字*/) { if (p_queue->head == p_queue->tail) { //队列是空的 return 0; } *p_val = p_queue->buf[p_queue->head]; //以head做下标的存储区里面就是最前面的数字,把它赋值给整数指针形式参数指向的存储区 p_queue->head++; //把head向后移动一步,这样下次获得的就是后面的数字(相当于把当前数字删除了) return 1; } //从队列里获得数字的函数(不会删除数字) int queue_front(const queue *p_queue, int *p_val) { if (p_queue->head == p_queue->tail) { //队列空的情况 return 0; } *p_val = p_queue->buf[p_queue->head]; return 1; }
2、queue.h内容
#ifndef __QUEUE_H__ #define __QUEUE_H__ typedef struct { int buf[SIZE]; //用来存放队列里的数字.前面的数字记录到小下标的存储区里,后面的数字记录到大下标的存储区里.只要最后一个存储区被使用过就认为队列已经被充满了,即使前面有空着的存储区也不可以使用 int head; //代表最前面的数字所在的下标.如果队列里没有数字则head应该等于tail int tail; //代表下一个数字应该放置的位置下标 } queue; //代表队列的结构体类型 //队列的初始化函数 void queue_init(queue */*指向调用函数提供的代表队列的结构体存储区*/); //队列的清理函数 void queue_deinit(queue *); //获得队列里数字个数的函数 int /*表示得到的数字个数*/queue_size(const queue *); //判断队列是否空的函数 int /*返回值为真表示队列空,否则不空*/queue_empty(const queue *); //判断队列是否满的函数 int /*返回值为真表示队列满,否则不满*/queue_full(const queue *); //向队列里加入数字的函数 int /*返回值为真表示成功加入,否则加入不成功*/queue_push(queue *, int /*要加入的数字*/); //从队列里获得数字的函数(同时删除数字) int /*返回值为真表示获得数字成功,否则失败*/queue_pop(queue *, int * /*用来向调用函数传递数字*/); //从队列里获得数字的函数(不会删除数字) int queue_front(const queue *, int *); #endif //__QUEUE_H__
3、主函数
#include <stdio.h> #include "queue.h" int main() { int val = 0; queue que = {0}; queue_init(&que); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_push(&que, 10); queue_push(&que, 20); queue_push(&que, 30); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_front(&que, &val); printf("最前面的数字是%d\n", val); queue_pop(&que, &val); printf("%d ", val); queue_pop(&que, &val); printf("%d\n", val); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_push(&que, 40); queue_push(&que, 50); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ while (1) { if (!queue_pop(&que, &val)) { //不能从队列里获得数字了 break; } printf("%d ", val); } printf("\n"); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_deinit(&que); return 0; } 运行结果: 数字个数是0 判断空的结果是1 判断满的结果是0 数字个数是3 判断空的结果是0 判断满的结果是0 最前面的数字是10 10 20 数字个数是1 判断空的结果是0 判断满的结果是0 数字个数是3 判断空的结果是0 判断满的结果是0 30 40 50 数字个数是0 判断空的结果是1 判断满的结果是0
二、循环队列
1、loop_queue.c文件内容
#include "loop_queue.h" //队列的初始化函数 void queue_init(queue *p_queue) { p_queue->tail = 0; //下一个数字应该放在下标为0的存储区里 p_queue->qty = 0; //队列里还没有数字 } //队列的清理函数 void queue_deinit(queue *p_queue) { p_queue->tail = 0; p_queue->qty = 0; } //计算第一个数字所在下标的函数 int /*得到的下标*/get_head(const queue *p_queue) { //如果tail是6,qty是3 //使用tail - qty可以得到第一个数字 //的下标 //如果tail是3,qty是6 //使用tail - qty + SIZE可以得到第一个 //数字的下标 int ret = p_queue->tail - p_queue->qty; if (ret < 0) { //最前面的数字在最后面数字的后面 ret += SIZE; } return ret; } //获得队列里数字个数的函数 int queue_size(const queue *p_queue) { return p_queue->qty; } //判断队列空的函数 int queue_empty(const queue *p_queue) { return !p_queue->qty; } //判断队列满的函数 int queue_full(const queue *p_queue) { return p_queue->qty >= SIZE; } //向队列里加入数字的函数 int queue_push(queue *p_queue, int val) { if (p_queue->qty >= SIZE) { //队列已经满了 return 0; } p_queue->buf[p_queue->tail] = val; p_queue->tail++; if (p_queue->tail >= SIZE) { //当最后一个存储区里已经放好数字后 //应该把tail设置成0,表示后面的 //数字应该从下标为0的存储区 //开始继续存放 p_queue->tail = 0; } p_queue->qty++; //数字个数加一 return 1; } //从队列里获得数字的函数(同时删除数字) int queue_pop(queue *p_queue, int *p_val) { if (!p_queue->qty) { //队列是空的 return 0; } *p_val = p_queue->buf[get_head(p_queue)]; //首先计算第一个数字所在存储区的下标,然后把这个存储区里的数字传递给调用函数 p_queue->qty--; //把数字个数减一,这导致最前面数字所在的下标向后移动一步(相当于删除最前面的数字) return 1; } //从队列里获得数字的函数(不会删除数字) int queue_front(const queue *p_queue, int *p_val) { if (!p_queue->qty) { //队列是空的 return 0; } *p_val = p_queue->buf[get_head(p_queue)]; return 1; }
2、loop_queue.h文件内容
#ifndef __LOOP_QUEUE_H__ #define __LOOP_QUEUE_H__ typedef struct { int buf[SIZE]; //用来存放队列里的数字.前面的数字存放在小下标的存储区里,后面的数字存放在大下标的存储区里.当最后一个存储区被使用过以后可以把后面的数字存放在下标为0的存储区里(前提条件是下标为0的存储区里没有有效数字) int qty; //记录队列里的数字个数 int tail; //记录下一个数字应该放置的存储区下标 } queue; //代表循环队列的结构体 //队列的初始化函数 void queue_init(queue *); //队列的清理函数 void queue_deinit(queue *); //获得队列里数字个数的函数 int queue_size(const queue *); //判断队列空的函数 int queue_empty(const queue *); //判断队列满的函数 int queue_full(const queue *); //向队列里加入数字的函数 int queue_push(queue *, int ); //从队列里获得数字的函数(同时删除数字) int queue_pop(queue *, int *); //从队列里获得数字的函数(不会删除数字) int queue_front(const queue *, int *); #endif //__03LOOP_QUEUE_H__
3、主函数内容
#include <stdio.h> #include "loop_queue.h" int main() { int val = 0; queue que = {0}; queue_init(&que); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_push(&que, 10); queue_push(&que, 20); queue_push(&que, 30); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_front(&que, &val); printf("最前面的数字是%d\n", val); queue_pop(&que, &val); printf("%d ", val); queue_pop(&que, &val); printf("%d\n", val); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_push(&que, 40); queue_push(&que, 50); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ while (1) { if (!queue_pop(&que, &val)) { //不能从队列里获得数字了 break; } printf("%d ", val); } printf("\n"); printf("数字个数是%d\n", queue_size(&que)/*获得队列里的数字个数*/); printf("判断空的结果是%d\n", queue_empty(&que)/*判断队列是否空*/); printf("判断满的结果是%d\n", queue_full(&que));/*判断队列是否满*/ queue_deinit(&que); return 0; } 运行结果: 数字个数是0 判断空的结果是1 判断满的结果是0 数字个数是3 判断空的结果是0 判断满的结果是0 最前面的数字是10 10 20 数字个数是1 判断空的结果是0 判断满的结果是0 数字个数是3 判断空的结果是0 判断满的结果是0 30 40 50 数字个数是0 判断空的结果是1 判断满的结果是0