运用数组组成顺序队列

最近学习了用数组构成循环队列,总结如下:
顺序队列基本操作

0. 定义一个队列
1. 队列初始化
2. 判断队列是否为空
3. 判断队列是否满
4. 复位队列
5. 获得队列有效元素长度
6. 入队
7. 出队
8. 遍历

rear 是指向队尾元素的下一个,front是指向队头元素

0.定义一个队列
定义一个管理队列的结构体
typedef uint8_t    queue_type;
typedef uint8_t    size_type;

#ifndef NULL
#define NULL ((void *)0)
#endif

#define FULL_JUDGE
#define LIB_QUEUE_DEBUG

typedef struct{
	queue_type * p_arr;
	size_type      front;//head
	size_type      rear; //tail
	size_type      size; 
	size_type      valid_len;//
}queue_t;
1. 队列初始化
初始化获得一个队列
/*
 *    out------------------in
 *<----a1,a2,a3,...,an     <----
 *      ^                ^
 *   front             rear
 *    head             tail
*/

/*
ret  1 success     0 fail
*/
uint8_t lib_init_queue(queue_t * p_queue,queue_type * buf, size_type size)
{
	if(buf == NULL) 
		return 0;
			
	p_queue->p_arr = buf;
	p_queue->valid_len = p_queue->front = p_queue->rear = 0;
	p_queue->size = size;
	  return 1;
}
2. 判断队列是否为空
当头指针和尾指针相等是则是空队列
/*
ret  1 empty     0 not empty
*/
uint8_t lib_queue_is_empty(queue_t * p_queue)
{
	if( (p_queue->front) == (p_queue->rear) )
	  return 1;
	return 0;
}
3.判断队列是否满
当尾指针加一对队列容量取余后等于头指针则队列已满
/*
ret  1 full     0 not full
*/
uint8_t lib_queue_is_full(queue_t * p_queue)
{
	if( ((p_queue->rear+1)%p_queue->size) == p_queue->front )
	  return 1;
	return 0;
}
4.复位队列
void reset_queue(queue_t * p_queue)
{
   p_queue->front = p_queue->rear = 0;
}
5.获得队列有效元素个数
/*
ret  queue len
情况1:当rear大于front时,队列元素个数:rear - front
情况2:当rear小于front时,队列元素个数分为2部分,0+rear 和 size-front,将2部分个数和起来
为rear-front+size
综上2种情况,元素个数是(rear-front+size) % size
*/
size_type lib_get_queue_len(queue_t * p_queue)
{
	  //(tail - head + size)%size
	  p_queue->valid_len = (p_queue->rear - p_queue->front + p_queue->size)%p_queue->size;
	  return p_queue->valid_len;
}
6.入队
入队之前要判断队列是否是满的
/*
ret  1 sucess     0 fail
*/
uint8_t lib_en_queue(queue_t * p_queue,queue_type m)
{
    #ifdef FULL_JUDGE // full judge
			if(lib_queue_is_full(p_queue) == 1)
				return 0;
    #endif
		
		p_queue->p_arr[(p_queue->rear)] = m; //add m to tail
		p_queue->rear = (p_queue->rear + 1)%p_queue->size; //updete rear
			return 1;
}
7.出队
出队之前要判断队列是否是已空
/*
ret  1 sucess     0 fail(empty)
*/
uint8_t lib_de_queue(queue_t * p_queue,queue_type * m)
{

		if(lib_queue_is_empty(p_queue) == 1)
			return 0;
		if(m != NULL)
			*m = p_queue->p_arr[p_queue->front]; //got *m
		
    #ifdef LIB_QUEUE_DEBUG
		   p_queue->p_arr[p_queue->front] = 0;
	#endif
		
		p_queue->front = (p_queue->front + 1)%p_queue->size; //updete front
			return 1;
}
8.遍历
下面是遍历队列里元素并求均值
/*
ret  queue avg
*/
queue_type lib_avg_queue(queue_t * p_queue)
{
		uint8_t i;
	  uint32_t sum=0;
	
		if(lib_queue_is_empty(p_queue) == 1)
			return 0;
		
		i = p_queue->front;
		
		while( i != p_queue->rear)
		{
			sum = sum + p_queue->p_arr[i];
			i = (i+1)%p_queue->size;
		}
		return sum/lib_get_queue_len(p_queue);
}
应用例子
#define BTRXSIZE 128
void main()
{
	uart_data_t btrx_fifo; //bt fifo manage struct      
	queue_type btrx_arr[BTRXSIZE]; //bt fifo arr
	
	lib_init_queue(&btrx_fifo.fifo,btrx_arr,BTRXSIZE);//初始化
	lib_en_queue(&btrx_fifo.fifo,USART_ReceiveData(USART1));//入队
	lib_de_queue(&uart_data->fifo,NULL); //出队
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值