如何实现入队,出队操作

队列一般使用,包括了入队,出对,获取长度

   queue.c

初始化

/********************************************************************************************************
*  @函数名   S_QueueEmpty                                                           
*  @描述     清空一个队列                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   无   
*  @注意    无
********************************************************************************************************/
void S_QueueEmpty(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff)
{
  *Head = HBuff;
  *Tail = HBuff;
}

入队

/********************************************************************************************************
*  @函数名   S_QueueDataIn                                                           
*  @描述     输入一个字节数据进队列                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   无   
*  @注意     无
********************************************************************************************************/
void S_QueueDataIn(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *HData, unsigned short DataLen)
{
unsigned short num;
unsigned char IptStatus;//IptStatus用于保存中断状态

    IptStatus = __get_interrupt_state();
        
disableInterrupts();//这两行代码保存当前的中断状态,并禁用中断
        
for(num = 0; num < DataLen; num++, HData++)
{
    **Tail = *HData; //数据赋值尾部
    (*Tail)++;//尾部往后移动
    if(*Tail == HBuff+Len)//尾部到数据最后
    *Tail = HBuff;//地址赋
    if(*Tail == *Head)//头和尾相等时,入的同时还在出列
    {
    if(++(*Head) == HBuff+Len)//两个都到尾部
    *Head = HBuff;//重新指向最开始
    }
}
__set_interrupt_state(IptStatus);//这行代码将之前保存的中断状态恢复,以便恢复中断
}

出队

/********************************************************************************************************
*  @函数名   S_QueueDataOut                                                           
*  @描述     从队列里取出一个数据                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   取出的数据   
*  @注意     无
********************************************************************************************************/
unsigned char S_QueueDataOut(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *Data)
{   
    unsigned char back = 0;//1-成功 0-失败
    unsigned char IptStatus;
    IptStatus = __get_interrupt_state();
        
    disableInterrupts();
    *Data = 0;
    if(*Tail != *Head)//检查队列是否非空
    {
    *Data = **Head;//将队列头部指向的数据赋值给*Data
    back = 1; 
    if(++(*Head) == HBuff+Len)
      //将队列头部指针递增,并确保它没有超过缓冲区的末尾,如果超过了,则将其回绕到缓冲区的开头。
    *Head = HBuff;
    }
    __set_interrupt_state(IptStatus);
    return back;
}

计算长度

/********************************************************************************************************
*  @函数名   S_QueueDataLen                                                           
*  @描述     判断队列里数据的长度                                     
*  @参数     Head-队列头地址,  Tail-队列尾地址,   HBuff-队列缓存
*  @返回值   队列里有数据个数
*  @注意     无
********************************************************************************************************/
unsigned short S_QueueDataLen(unsigned char **Head, unsigned char **Tail, unsigned short Len)
{
    if(*Tail > *Head)
//Tail除了开始是和它相等(为空),后面都会往后移动1位,所以4个字节满时,已经到数组第5个地址了
        return *Tail-*Head;
    if(*Tail < *Head)
        return *Tail+Len-*Head;
//不断入列,也不断出列,导致tail<head,Len都比数组大1
    return 0;
}

queue.h文件

#ifndef _QUEUE_H_
#define _QUEUE_H_ 

extern void S_QueueEmpty(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff);
extern void S_QueueDataIn(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *HData, unsigned short DataLen);
extern unsigned char S_QueueDataOut(unsigned char **Head, unsigned char **Tail, unsigned char *HBuff, unsigned short Len, unsigned char *Data);
extern unsigned short S_QueueDataLen(unsigned char **Head, unsigned char **Tail, unsigned short Len);
 
#define QueueEmpty(x)   S_QueueEmpty((unsigned char**)&(x).Head,(unsigned char**)&(x).Tail,(unsigned char*)(x).Buff) 
#define QueueDataIn(x,y,z) S_QueueDataIn((unsigned char**)&(x).Head,(unsigned char**)&(x).Tail,(unsigned char*)(x).Buff,sizeof((x).Buff),(y),(z))
#define QueueDataOut(x,y)  S_QueueDataOut((unsigned char**)&(x).Head,(unsigned char**)&(x).Tail,(unsigned char*)(x).Buff,sizeof((x).Buff),(y)) 
#define QueueDataLen(x)   S_QueueDataLen((unsigned char**)&(x).Head,(unsigned char**)&(x).Tail,sizeof((x).Buff))  

/* 队列结构体定义,定义不同大小的队列 */
typedef struct
{
unsigned char *Head; 
unsigned char *Tail; 
unsigned char Buff[4+1];
}Queue4;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[8+1];}Queue8;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[16+1];}Queue16; 
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[32+1];}Queue32;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[64+1];}   Queue64;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[90+1];}   Queue90;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[120+1];}  Queue120;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[128+1];}  Queue128;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[248+1];}  Queue248;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[256+1];}  Queue256;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[250+1];}  Queue250;

typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[512+1];}  Queue512;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[1024+1];} Queue1K;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[2048+1];} Queue2K;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[5120+1];} Queue5K;
typedef struct{unsigned char *Head; unsigned char *Tail; unsigned char Buff[10240+1];} Queue10K;

#endif

循环队列是一种基于数组实现的队列,它可以避免数组队列在队列头出队后,后续元素需要依次向前移动的问题。以下是一个简单的循环队列实现,包括入队出队、判断队空、判断队满的操作。 ```python class CircularQueue: def __init__(self, capacity): self.capacity = capacity self.queue = [None] * capacity self.front = 0 self.rear = 0 def enqueue(self, data): if self.is_full(): print("Queue is full!") return self.queue[self.rear] = data self.rear = (self.rear + 1) % self.capacity def dequeue(self): if self.is_empty(): print("Queue is empty!") return None data = self.queue[self.front] self.queue[self.front] = None self.front = (self.front + 1) % self.capacity return data def is_empty(self): return self.front == self.rear and self.queue[self.front] is None def is_full(self): return self.front == self.rear and self.queue[self.front] is not None ``` 在这个实现中,我们用一个固定大小的数组来存储队列元素,通过 front 和 rear 两个指针来维护队列头和队列尾的位置。当队列满时,rear 指针会指向队列头,此时我们需要判断队列是否满的条件是 front == rear 且队列头不为 None。当队列空时,front 和 rear 指针相等且队列头为 None。当入队时,我们首先判断队列是否已满,若已满则返回错误信息,否则将数据存入 rear 指针所指位置并将 rear 指针后移一位。当出队时,我们首先判断队列是否为空,若为空则返回错误信息,否则将队列头元素取出并将 front 指针后移一位。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值