画解数据结构刷题之队列之FIFO队列

这篇博客探讨了如何使用简单队列和滑动窗口解决两个实际问题。第一部分展示了如何通过队列计算购票所需时间,而第二部分则介绍了如何利用滑动窗口计算最近3000毫秒内的请求数量,以及如何实现移动平均值的计算。博客还提供了链表实现队列的代码模板,并讲解了结构体和指针的使用。

简单队列

第一题

int timeRequiredToBuy(int* tickets, int ticketsSize, int k){
int cnt=0;
int i=0;
while(tickets[k]!=0)
{
        if(tickets[i]>0)
        {
            tickets[i]--;
            cnt++;
        }
        i++;
        if(i==ticketsSize)
        {
            i=0;
        }
    }
return cnt;
}
typedef struct 
{
    int idx;
    int need;
}Queue;
int timeRequiredToBuy(int* tickets, int ticketsSize, int k){
Queue q[50000];//队列,数组存类
Queue temp;
int front=0;
int rear=0;
//将第一批人入队
for(int i=0;i<ticketsSize;i++)
{
    q[rear]->idx=i;
    q[rear]->need=tickets[i];
    rear++;
}
int time=0;
while(front<rear)
{
    Queue temp=q[front];
    front++;
    temp->need--;
    time++;
    if(temp->need)
    {
        q[rear++]=temp;//重新入队
    }
    else{
        if(temp->idx==k)
        {
            return time;
        }
    }
}
return 0;
}

q[rear++]=temp;让其重新入队

滑动窗口

第一题

struct Data {
    int time;                                        // (1) 
};

/**************************** 链表 实现队列 ****************************/
#define DataType struct Data
#define maxn 100005

struct QueueNode;

struct QueueNode {
    DataType data;
    struct QueueNode *next;
};

struct Queue {
    struct QueueNode *head, *tail;
    int size;
};

void QueueEnqueue(struct Queue *que, DataType dt) {
    struct QueueNode *insertNode = (struct QueueNode *) malloc( sizeof(struct QueueNode) );
    insertNode->data = dt;
    insertNode->next = NULL;
    if(que->tail) {
        que->tail->next = insertNode;
        que->tail = insertNode;
    }else {
        que->head = que->tail = insertNode;
    }
    ++que->size;
}

void QueueDequeue(struct Queue* que) {
    struct QueueNode *delNode = que->head;
    que->head = delNode->next;
    free(delNode);
    --que->size;
}

DataType QueueGetFront(struct Queue* que) {
    return que->head->data;
}
int QueueGetSize(struct Queue* que) {
    return que->size;
}
int QueueIsEmpty(struct Queue* que) {
    return !QueueGetSize(que);
}
void QueueClear(struct Queue* que) {
    que->head = que->tail = NULL;
    que->size = 0;
}

队列用链表实现模板

typedef struct {
struct Queue q;//是一个队列
} RecentCounter;


RecentCounter* recentCounterCreate() {
RecentCounter*ret=(RecentCounter*)malloc(sizeof(RecentCounter));
QueueClear(&ret->q);
return ret;
}

int recentCounterPing(RecentCounter* obj, int t) {
DataType dt;//当前信息
DataType front;
dt.time=t;
//设置一个指向队列的指针,来做传参
struct Queue*temp=&obj->q;
QueueEnqueue(temp,dt);//将当前元素入队
while(!QueueIsEmpty(temp))//当队列不空
{
front=QueueGetFront(temp);
if(dt.time-front.time>3000)
{
    QueueDequeue(temp);
}
else{
    break;
}
}
return QueueGetSize(temp);
}

void recentCounterFree(RecentCounter* obj) {
free(obj);
}

注意: 

struct Queue*temp=&obj->q;

此处要加&,是因为要用temp代替obj->q的地址,因为调用函数时都有*

第二题

 将sum构筑于结构体中,每次加入元素就+=

MovingAverage* movingAverageCreate(int size) {
MovingAverage*ret=(MovingAverage*)malloc(sizeof(MovingAverage));
QueueClear(&ret->q);
ret->ssize=size;
ret->sum=0;
return ret;
}

double movingAverageNext(MovingAverage* obj, int val) {
DataType dt;//当前元素
dt.num=val;
obj->sum+=val;
struct Queue*temp=&obj->q;
QueueEnqueue(temp,dt);
double qsize=QueueGetSize(temp);
while(qsize>obj->ssize)
{
    DataType front=QueueGetFront(temp);
    obj->sum-=front.num;
    QueueDequeue(temp);//让队首的出去
    qsize--;
}
return obj->sum/QueueGetSize(temp);
}

void movingAverageFree(MovingAverage* obj) {
free(obj);
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值