队列是一种特殊的表,只在表首进行删除,只在表尾进行插入,按照先进先出原则操作(First In First Out),又称为FIFO表;
队列的指针实现代码:
#include<cstdio> #include<cstdlib> #include<algorithm> typedef struct node* link; typedef struct node { int element; link next; }Node; typedef struct aque* Queue; typedef struct aque { link front; //队首节点指针 link last; //队尾节点指针 }Aque; Queue QueueInit(Queue Q) { Q->front=Q->last=0; return Q; } int QueueEmpty(Queue Q) { return Q->front==0; } int QueueFull(Queue Q) { //这里个人认为通过指针实现的队列(在现阶段我的使用中)可以不需要判断队列空间是否已满; } int QueueFirst(Queue Q) { return Q->front->element; } int QueueLast(Queue Q) { return Q->last->element; } void EnterQueue(int x,Queue Q) { link p; p=new Node; //创建一个新的节点 p->element=x;p->next=0; if(Q->front) //如果队列非空 { Q->last->next=p; } else Q->front=p; //空队列 Q->last=p; } int DeleteQueue(Queue Q) { link p; int x=Q->front->element; p=Q->front; Q->front=Q->front->next; free(p); return x; } int main() { int i,j,k; Queue Q=new Aque; QueueInit(Q); EnterQueue(5,Q); EnterQueue(2,Q); printf("%d",QueueFirst(Q)); DeleteQueue(Q); EnterQueue(0,Q); while(QueueEmpty(Q)!=1) { printf("%d",QueueFirst(Q)); DeleteQueue(Q); } return 0; }
用循环数组实现队列代码:
循环数组的形状如下:
#include<cstdio> #include<cstdlib> #include<malloc.h> typedef struct aque* Queue; typedef struct aque { int maxsize; int front; //队头游标 int last; //队尾游标 int* queue; }Aque; Queue QueueInit(int size,Queue Q) { Q->queue=(int*)malloc(size*sizeof(int)); Q->maxsize=size; Q->front=Q->last=0; return Q; } int QueueEmpty(Queue Q) { return Q->front==Q->last; //如果此时队列是空的,那么front和last游标在同一个位置 ; } int QueueFull(Queue Q) { return (((Q->last+1)%Q->maxsize==Q->front)?1:0); //如果此时队列是满的那么front和last是游标相邻的; } int QueueFirst(Queue Q) { return Q->queue[(Q->front+1)%Q->maxsize]; } int QueueLast(Queue Q) { return Q->queue[Q->last]; } void EnterQueue(int x,Queue Q) { Q->last=(Q->last+1)%Q->maxsize; Q->queue[Q->last]=x; } int DeleteQueue(Queue Q) { Q->front=(Q->front+1)%Q->maxsize; return Q->queue[Q->front]; } int main() { int i,j,n; scanf("%d",&n); Queue Q=new Aque; QueueInit(n,Q); EnterQueue(5,Q); EnterQueue(2,Q); printf("%d",DeleteQueue(Q)); EnterQueue(0,Q); while(QueueEmpty(Q)!=1) { printf("%d",QueueFirst(Q)); DeleteQueue(Q); } return 0; }
思想:通过游标指向的变化,来判断队列是否已经满或者空;
栈在STL中有直接的函数可以使用,队列也是一样的,需要包括的文件时queue;
STL中队列使用代码:
#include<cstdio> #include<cstdlib> #include<iostream> #include<queue> using namespace std; queue<int> q; int main() { int i,j,n; scanf("%d",&n); for(i=1;i<=n;i++) { int tmp; scanf("%d",&tmp); q.push(tmp); } printf("%d",q.front()); q.pop(); while(q.empty()!=1) { printf("%d",q.front()); q.pop(); } return 0; }
第四次作业:
1、(计算一个数列中长度不超过k的数字之和的最大值):这种数列中某个长度对数字的操作,一般可以通过单调队列写;单调队列(最大值队列)思想是:只需要维护一个递减的数组,每次要输入到维护中的数如果比数组中最后的数小,直接加入,否则,数组中的数一定不是结果,则将其替换成要输入的这个数;具体理解可以看之前的一篇博客,里面也有单调队列相关的例题及代码;
这题先对数列求其前缀和(每个数其前面所有数的和),通过一个que数组存储sum的下标,维护这个que数组使之存储的下标其sum数组值中是一个递增的序列(因为通过每次存储比之更大的,就已经对所有的更大的sum都做了一个if判断,储存了其中的max);
代码:
#include<stdio.h> #include<iostream> using namespace std; const int Len = 100000 + 5; int a[Len], que[Len], top, tail; int main() { int n, k, ans = -100000000, l, r, i; cin >> n >> k; que[top++] = 0; l = 1; r = 1; for (i = 1; i <= n; i++) { cin >> a[i]; a[i] += a[i - 1]; while (top>tail&&i - que[tail]>k)tail++; if (ans<a[i] - a[que[tail]]) { ans = a[i] - a[que[tail]]; l = que[tail] + 1; r = i; } while (top>tail&&a[que[top - 1]]>a[i]) {top--;} que[top++] = i; } printf("%d %d %d\n", ans, l, r); }
第二题:(队列的基础运算用法):直接用一个队列将数字存储,然后按照题面意思对队列做删除等操作,就可以解出来;
来源:https://www.cnblogs.com/heihuifei/p/8065120.html