与栈不一样,他就是现实中排队同样,讲究先来后到,即 先进先出。
打个比方,你告诉朋友咱们作地铁去西湖,你输入 "s-u-b", 若是按照栈 先入后出后入先出 的方式,朋友会收到 b-u-s, what?有地铁,咱们干吗作两个小时的汽车??? 队列就可让朋友按你输入的顺序依次收到 s-u-b 。bash
简单的看一下队列,是线性结构,想到什么?很是熟悉的 线性表 ,有两种存储结构,顺序存储和链式存储。 咱们今天先讲一讲队列的顺序存储结构——循环队列markdown
可是,,,若是以下图,出队到只剩最后一个元素,front和rear又都指向了一个同元素,并且仅在队尾,又要认为队列为空?不可能啊,明明最后一块存储单元还有一个元素,并且却不能继续入队新元素,超出了存储范围,若是要继续利用前面出队的空余空间,又该怎么用?函数
若是 咱们把队列设计成下面这样:测试
这就是循环队列的工做流程spa
将上面的过程作一下整理:
设计
#define ERROR 0 #define TRUE 1 #define FALSE 0 #define OK 1 #define MAXSIZE 20 /* 存储空间初始分配量 */ typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */ typedef int ElemType;/* ElemType类型根据实际状况而定,这里假设为int */ /* 队列结构 */ typedef struct { ElemType *data; int front; /* 记录队首元素位置 */ int rear; /* 记录对尾元素位置 */ int max; /* 记录开辟内存空间的大小 */ }SqQueue; 复制代码
/// 初始化建立队列 /// @param Q 队列指针 /// @param n 指定开辟空间大小,一个空间大小是 sizeof(ElemType) Status InitQueue(SqQueue *Q, int n) { Q->data = malloc(sizeof(ElemType) * n); if (Q->data == NULL) return ERROR; Q->max = n; Q->front = Q->rear = 0; return OK; } 复制代码
/// 获取队列元素个数(包括rear指向的空位置) /// @param Q 队列 int GetLength(SqQueue Q) { return (Q.rear - Q.front + Q.max) % Q.max; } 复制代码
Status QueueEmpty(SqQueue Q) { if (Q.front == Q.rear) { return OK; } return ERROR; } 复制代码
Status QueueFull(SqQueue Q) { if ((Q.rear+1) % Q.max == Q.front) { return OK; } else { return ERROR; } } 复制代码
Status GetFront(SqQueue Q, ElemType *e) { if (QueueEmpty(Q) == OK) { return ERROR; } *e = Q.data[Q.front]; return OK; } 复制代码
/// 入队操做 /// @param Q 队列 /// @param e 新数据 Status EnQueue(SqQueue *Q, ElemType e) { // 判断队列有没有满 if (QueueFull(*Q)) return ERROR; Q->data[Q->rear] = e; // 队尾向后移动,取模运算,超出队尾,实现循环继续从队首开始 Q->rear = (Q->rear+1) % Q->max; return OK; } 复制代码
/// 出队列 /// @param Q 队列 /// @param e 出的元素 Status DeQueue(SqQueue *Q, ElemType *e) { // 判断对了是否是空 if (QueueEmpty(*Q) == OK) return ERROR; *e = Q->data[Q->front]; // 队首位置向后移动一位 Q->front = (Q->front+1) % Q->max; return OK; } 复制代码
Status QueuePrint(SqQueue *Q) { /* 从队首开时输出,直到对尾 */ int i = Q->front; while (i != Q->rear) { printf("%d ",Q->data[i]); i = (i+1) % Q->max; } printf("\n"); return ERROR; } 复制代码
指定队列最大存储5个单元,方便观看指针
int main(int argc, const char * argv[]) { SqQueue queue; InitQueue(&queue, 5); printf("插入数据:"); for (int i = 0; i < 30; i++) { EnQueue(&queue, i); } QueuePrint(&queue); int e ; printf("出队:"); if (DeQueue(&queue, &e)) { QueuePrint(&queue); } if (DeQueue(&queue, &e)) { QueuePrint(&queue); } int frontE; if (GetFront(queue, &frontE)) { printf("队头:%d\n",frontE); } printf("插入数据:"); scanf("%d",&e); EnQueue(&queue, e); QueuePrint(&queue); printf("插入数据:"); scanf("%d",&e); EnQueue(&queue, e); QueuePrint(&queue); printf("插入数据:"); scanf("%d",&e); EnQueue(&queue, e); QueuePrint(&queue); printf("插入数据:"); scanf("%d",&e); EnQueue(&queue, e); QueuePrint(&queue); printf("开始清空队列\n"); ClearQueue(&queue); QueuePrint(&queue); DestoryQueue(&queue); return 0; } 复制代码