队列
定义:具有一定操作约束的线性表
插入和删除操作:一端插入(入队),一端删除(出队)
先进先出
队列的顺序存储实现(循环队列)
一个一维数组,一个头元素位置变量,一个为尾元素位置变量
如何判断队列的空/满?
使用额外标记 / 仅使用n-1个空间(判断头尾是否相遇)
#define ERROR -1;
typedef int Position;
typedef int ElementType;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode *Queue;
Queue CreateQueue( int MaxSize ){
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
Q->Front = Q->Rear = 0;
Q->MaxSize = MaxSize;
return Q;
}
bool IsFull( Queue Q ){
return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}
bool AddQ( Queue Q, ElementType X ){
if ( IsFull(Q) ) {
printf("队列满");
return false;
}
else {
Q->Rear = (Q->Rear+1)%Q->MaxSize;
Q->Data[Q->Rear] = X;
return true;
}
}
bool IsEmpty( Queue Q ){
return (Q->Front == Q->Rear);
}
ElementType DeleteQ( Queue Q ){
if ( IsEmpty(Q) ) {
printf("队列空");
return ERROR;
}
else {
Q->Front =(Q->Front+1)%Q->MaxSize;
return Q->Data[Q->Front];
}
}
队列的链式存储实现
#include<stdio.h>
#include<stdlib.h>
#define ERROR -1;
typedef int Position;
typedef int ElementType;
struct QNode {
ElementType *Data; /* 存储元素的数组 */
Position Front, Rear; /* 队列的头、尾指针 */
int MaxSize; /* 队列最大容量 */
};
typedef struct QNode *Queue;
Queue CreateQueue( int MaxSize ){
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
Q->Front = Q->Rear = 0;
Q->MaxSize = MaxSize;
return Q;
}
bool IsFull( Queue Q ){
return ((Q->Rear+1)%Q->MaxSize == Q->Front);
}
bool AddQ( Queue Q, ElementType X ){
if ( IsFull(Q) ) {
printf("队列满");
return false;
}
else {
Q->Rear = (Q->Rear+1)%Q->MaxSize;
Q->Data[Q->Rear] = X;
return true;
}
}
bool IsEmpty( Queue Q ){
return (Q->Front == Q->Rear);
}
ElementType DeleteQ( Queue Q ){
if ( IsEmpty(Q) ) {
printf("队列空");
return ERROR;
}
else {
Q->Front =(Q->Front+1)%Q->MaxSize;
return Q->Data[Q->Front];
}
}
队列的应用—打印杨辉三角
求解问题基本思路:根据n-1层的数,计算出n层的数并将其打印,及先打印先计算,故选择队列的存储方式
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
typedef int QElemType;
#define QUEUE_INIT_SIZE 100
#define QUEUEINCREMENT 10
struct SqQueue{
QElemType *elem;
int top;
int rear;
int queuesize;
int incrementsize;
};
void InitQueue_sq(SqQueue &Q){
Q.elem=new QElemType[QUEUE_INIT_SIZE+1];
//为循环队列分配空间(比实际能用多一个元素)
Q.queuesize=QUEUE_INIT_SIZE+1;
Q.incrementsize=QUEUEINCREMENT;
Q.top=Q.rear=0;
}
void EnQueue(SqQueue &Q,QElemType e){
//插入元素e为Q的新的队尾元素
if((Q.rear+1)%Q.queuesize==Q.top){//队满的判断
QElemType *a;
a=new QElemType [Q.queuesize+Q.incrementsize];
for(int k=0;k<Q.queuesize-1;k++) a[k]=Q.elem[(Q.top+k)%Q.queuesize];//腾挪原循环队列中的数据元素
delete Q.elem;
Q.elem=a;
Q.top=0;
Q.rear=Q.queuesize-1;
Q.queuesize+=Q.incrementsize;
}
Q.elem[Q.rear]=e;
Q.rear=(Q.rear+1)%Q.queuesize;//入队,rear表示真正队尾的下一个元素的下标
}
int getLength(SqQueue Q){ return (Q.top+Q.queuesize-Q.rear)%Q.queuesize; }
bool DeQueue(SqQueue &Q,QElemType &e){
if(Q.top==Q.rear) return false;//空队列
e=Q.elem[Q.top];
Q.top=(Q.top+1)%Q.queuesize;
return true;
}
void ClearQueue(SqQueue &Q){ Q.top=Q.rear=0; }
void DestroyQueue(SqQueue &Q) {
delete Q.elem;
Q.elem=NULL;
Q.top=Q.rear=0;
}
bool isEmpty(SqQueue Q) {
if(Q.top==Q.rear) return true;
return false;
}
void getHead(SqQueue Q,QElemType &e){ e=Q.elem[Q.top];}
void QueueTraverse(SqQueue Q) {
int i=Q.top;
while(i!=Q.rear){
cout<<Q.elem[i]<<" ";
i=(i+1)%Q.queuesize;
}
printf("\n");
}
void InitQueue(SqQueue &Q,int n) {
Q.elem=new QElemType[n];
//为循环队列分配空间(比实际能用多一个元素)
Q.queuesize=n;
Q.incrementsize=QUEUEINCREMENT;
Q.top=Q.rear=0;
}
void Triangle(int n) {
SqQueue Q;
int i,k;
for(i=1;i<n;i++) cout<<" ";
cout<<"1"<<endl;//在中心位置输出杨辉三角形的最顶端的1
InitQueue(Q,n+2);//设置最大容量为n+2的空队列,且因为循环队列的创建队列的函数不含int型参数,所以定义调用了InitQueue()函数来创建空队列
EnQueue(Q,0);//添加临界值0
EnQueue(Q,1);
EnQueue(Q,1);//第二行的值入队列
k=2;//k表示行数
QElemType e,s;
while(k<n){
for(i=1;i<=n-k;i++) cout<<" ";
EnQueue(Q,0);//行界值0入队
do{
DeQueue(Q,s);
getHead(Q,e);
if(e) cout<<e<<" ";//若e为非0值,则打印输出e的值并加一空格
else cout<<endl;//否则换行,为下一行的输出做准备
EnQueue(Q,s+e);
}while(e!=0);
k++;
}
DeQueue(Q,e);
QueueTraverse(Q);
}
int main() {
int n;
printf("n=");
scanf("%d",&n);
Triangle(n);
return 0;
}
离散事件模拟
建立事件表
记录进程的进入和离开
按事情发生的先后顺序逐个处理事件
程序以事件表为空告终