首先是简单队列,也不多说了
使用数组结构创建队列:
队列定义代码:
#include<stdio.h> #define MAX_SIZE 10 int queue[MAX_SIZE]; int rear = -1; int front = -1;
队列操作代码:
int InQueue(int value) { if(rear >= MAX_SIZE) return 0; rear ++; queue[rear] = value; return 1; } int OutQueue(int *value) { if(front == rear) return 0; front ++; *value = queue[front]; return 1; }
测试代码:
void main() { int temp; while(1) { printf("1:存入;2:读取;+》:"); scanf("%d",&temp); //清空临时缓冲区 fflush(stdin); if(temp == 1) { printf("请输入要存入的值:"); scanf("%d",&temp); fflush(stdin); if(InQueue(temp) == 1) printf("插入队列成功!\n"); else printf("队列已满!\n"); }else if(temp == 2){ //取数据 if(OutQueue(&temp)) { printf("读取队列值为:%d\n",temp); }else printf("队列为空\n"); }else break; } }
接着介绍下循环队列:
上面的状态是先插入4个元素,然后全部取出,再插入5个元素的状态。这时候单向队列已经满了。
当队尾达到边界的时候,可以发现队列已经不能再存入数据了,然而队首还有一些空的区域。
为了弥补单队列的这个缺点,我们可以利用循环队列来实现重复利用这些空闲空间。
首先将队尾移到数据区域的头部,并且插入数据,那么空闲的区域又可以重复使用了。
这里的插入队列函数写作:
int InQueue(int value) { //判断队满 //1.队头一个数据都没取,且队尾到了边界 //2.队尾已经反过来(队头已经取过数据)队尾下一个为队头 //事实上这里浪费了一个空间,因为我们在出数据的时候还要判断一个队空 //队头一直在取,去最后一个的时候队头与队尾相等,作为队空的条件 if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front) return 0; rear++; if(rear == MAX_SIZE) rear = 0; queue[rear] = value; return 1; }
下面是出队函数:
int OutQueue(int *value) { if(rear == front) return 0; front++; if(front == MAX_SIZE) front = 0; *value = queue[front]; return 1; }
可以看到思成在这里充分考虑了两种情况,普遍情况是队尾在队首前面一位的时候,这时候不能再插入了,还有一种特殊情况会使队尾在队首前面, 那就是队尾在最后一位而队首刚好在数据域第一个的时候,条件中也排除了这种情况。(如下图)
还有一种思路,就是《严版数据结构里的》,更加简洁,将这两种情况结合起来考虑了。
int InQueue(int value) { //if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front) if((rear+1) % MAX_SIZE == front) return 0; //rear++; //if(rear == MAX_SIZE) rear = 0; rear = (rear + 1) % MAX_SIZE; queue[rear] = value; return 1; }
出队列也可以相应的改成:
int OutQueue(int *value) { if(rear == front) return 0; //front++; //if(front == MAX_SIZE) front = 0; front = (front + 1) % MAX_SIZE; *value = queue[front]; return 1; }
队列还可以通过链表的存储方式来表示(链式存储):
#include<stdio.h> #include<stdlib.h> typedef struct _queue_node { int data; struct _queue_node * next; }QUEUE; QUEUE * rear = NULL; QUEUE * front = NULL; int InQueue(int value) { QUEUE * q = (QUEUE *)malloc(sizeof(QUEUE)); if(q == NULL) return 0; q->data = value; q->next = NULL; if(front == NULL) front = q; else rear->next = q; rear = q; return 1; } int OutQueue(int *value) { QUEUE * p = NULL; if(front == NULL) return 0; p = front; front = front->next; *value = p->data; free(p); return 1; }