1.队列是线性表的一种,在操作数据元素时,和栈一样,有自己的规则:使用队列存取数据元素时,数据元素只能从表的一端进入队列,另一端出队列
2.队列的顺序表示和实现
使用顺序存储结构表示队列时,首先申请足够大的内存空间建立一个数组,除此之外,为了满足队列从队尾存入数据元素,从队头删除数据元素,还需要定义两个指针分别作为头指针和尾指针。
当有数据元素进入队列时,将数据元素存放到队尾指针指向的位置,然后队尾指针增加 1;当删除对头元素(即使想删除的是队列中的元素,也必须从队头开始一个个的删除)时,只需要移动头指针的位置就可以了。
顺序表示是在数组中操作数据元素,由于数组本身有下标,所以队列的头指针和尾指针可以用数组下标来代替,既实现了目的,又简化了程序。
例如,将队列(1,2,3,4)依次入队,然后依次出队并输出。
3.代码
#include <stdio.h>
int enQueue(int *a,int rear,int data) {//定义入队构造函数
a[rear] = data;
rear++;
return rear;
}
int deQueue(int *a,int front,int rear) {//定义出队构造函数
//若rear=front,表示队列为空
while (rear != front) {
printf("%d", a[front]);
front++;
}
}
int main() {
int a[100];//设置一个数组空间大小100,
int front, rear;//设置队列的头指针,尾指针
front = rear = 0;//当队列中没有元素时,队头和队尾指向同一块指针
//入队函数:enQueue
rear = enQueue(a, rear, 1);
rear = enQueue(a, rear, 2);
rear = enQueue(a, rear, 3);
rear = enQueue(a, rear, 4);
//出队函数:deQueue
front = deQueue(a, front, rear);
return 0;
}
运行结果:
5.顺序存储的升级版
使用数组存取数据元素时,可以将数组申请的空间想象成首尾连接的环状空间使用。例如,在申请的内存空间大小为 5 的情况下,将数字 1-6 进队后再出队(普通方式中 6 是无法进队的):
代码实现:
#include <stdio.h>
#define max 5 //定义空间大小为5,这样子6是无法进队的
int enQueue(int *a, int front,int rear, int data) {//定义入队构造函数
//若首尾指针和头指针重合,则证明数据存满了
if ((rear+1)%max==front) {
printf("空间已满");
return rear;
}
a[rear%max] = data;
rear++;
return rear;
}
int deQueue(int *a, int front, int rear) {//定义出队构造函数
//若rear=front,表示队列为空
if (front == rear) {
printf("队列为空");
return front;
}
printf("%d", a[front]);
front=(front+1)%max;
return front;
}
int main() {
int a[max];//设置一个数组空间大小max,
int front, rear;//设置队列的头指针,尾指针
front = rear = 0;//当队列中没有元素时,队头和队尾指向同一块指针
//入队函数:enQueue
rear = enQueue(a, front,rear, 1);
rear = enQueue(a, front, rear, 2);
rear = enQueue(a, front, rear, 3);
rear = enQueue(a, front, rear, 4);
//出队函数:deQueue
front = deQueue(a, front, rear);
rear = enQueue(a, front,rear, 5);
front = deQueue(a, front, rear);
rear = enQueue(a, front, rear, 6);
front = deQueue(a, front, rear);
front = deQueue(a, front, rear);
front = deQueue(a, front, rear);
front = deQueue(a, front, rear);
return 0;
}
结果:
6.队列的链式表示和实现(简称为“链队列”)
队列的链式存储是在链表的基础上,按照“先进先出”的原则操作数据元素。
例如,将队列(1,2,3,4)依次入队,然后再依次出队。
代码:
#include <stdio.h>
#include <stdlib.h>
//定义QNode结构体
typedef struct QNode {
int data;
struct QNode * next;//定义了一个指针
}QNode;
QNode * initQueue() {//初始化
QNode * queue = (QNode*)malloc(sizeof(QNode));//分配空间
queue->next = NULL;//指向最后为空
return queue;
}
QNode* enQueue(QNode * rear, int data) {
QNode * enElem = (QNode*)malloc(sizeof(QNode));//分配空间
enElem->data = data;
enElem->next = NULL;
//使用尾插法向链队列中添加数据元素
rear->next = enElem;
rear = enElem;
return rear;
}
void DeQueue(QNode * front, QNode * rear) {
if (front->next == NULL) {
printf("队列为空");
return;
}
QNode * p = front->next;
printf("%d", p->data);
front->next = p->next;
if (rear == p) {
rear = front;
}
free(p);
}
int main() {
QNode * queue, *front, *rear;
queue = front = rear = initQueue();//创建头结点
//向链队列中添加结点,使用尾插法添加的同时,队尾指针需要指向链表的最后一个元素
rear = enQueue(rear, 1);
rear = enQueue(rear, 2);
rear = enQueue(rear, 3);
rear = enQueue(rear, 4);
//入队完成,所有数据元素开始出队列
DeQueue(front, rear);
DeQueue(front, rear);
DeQueue(front, rear);
DeQueue(front, rear);
DeQueue(front, rear);
return 0;
}
结果: