队列
在实际生活中队列的用处随处可见,只要是排队的地方都会出现这样的结构
队列和栈差不多都是对于数据的存和取有严格要求的线性结构
和栈结构与所不同的是,队列是两端开口,要求数据从一端进,必须要从另一端出
通常我们将进数据的一段称为“队尾”,出数据的一段称为“队头”,数据元素进队列的过程称为“入队”,出队列的过程称为“出队”。而且队列要遵守先进先出的原则。
队列和栈一样也拥有两种实现方式:
- 顺序队列:在顺序表的基础上实现队列结构;
- 链队列:在链表的基础上实现队列;
顺序队列
简单实现
由于顺序队列的底层使用的是数组,因此需要预先审批一块足够大的内存空间初始化顺序队列。除此之外,为了满足顺序队列中数据从队尾进,队头出且先进先出的要求,我们就需要定义两个指针top和rear分别用于指向队尾元素和队头元素。
这是一开始我们创建顺序队列时两个指针都指向同一个位置
这是开始后输入数据随着数据增加rear指针指队头。
这是输出时数据的走向。
#include <stdio.h>
int enQueue(int * a, int rear, int data){
a[rear++]=data;
return rear;
}
void deQueue(int * a, int top, int rear){
while(front!=rear){
printf("出队元素:%d\n",a[top++]);
}
}
int main(){
int a[100];
int top,rear;
top=rear=0;
rear=enQueue(a,rear,1);
rear=enQueue(a,rear,2);
rear=enQueue(a,rear,3);
rear=enQueue(a,rear,4);
deQueue(a,top,rear);
return 0;
}
此方法是存在缺陷的,我们看上面的图片,就不难看出这样的顺序队列会造成大量的资源浪费,顺序队列使用过的地方也必能再用,而顺序队列自己也不会再往回走了,造成了整体后移的效果。如果申请的空间不足就会造成溢出产生错误。
循环队列
说白了就是将上面的方法进行改进使他成为一个圆环。
其实这只是一个想象图,我们完全没有必要真的是新这样一种结构,还用之前的程序,我们做一些小小的修改。
#include <stdio.h>
#define max 5
int enQueue(int * a, int top, int rear, int data){
if((rear+1)%max==top){
printf("空间已满");
return rear;
}
a[rear%max]=data;
rear++;
return rear;
}
int deQueue(int * a, int top, int rear){
if(top==rear%max){
printf("队列为空");
return top;
}
printf("%d",a[top]);
top=(top+1)%max;
return top;
}
int main(){
int a[max];
int top, rear;
top=rear=0;
rear=enQueue(a,top,rear,1);
rear=enQueue(a,top,rear,2);
rear=enQueue(a,top,rear,3);
rear=enQueue(a,top,rear,4);
top=deQueue(a,top,rear);
rear=enQueue(a,top,rear,5);
top=deQueue(a,top,rear);
rear=enQueue(a,top,rear,6);
top=deQueue(a,top,rear);
top=deQueue(a,top,rear);
top=deQueue(a,top,rear);
top=deQueue(a,top,rear);
return 0;
}
使用此方法需要注意:
- 当队列为空时队列头指针等于队列尾指针;
- 当数组满员时队列头指针等于队列尾指针;
链队列
说白了就是用链式存储结构实现队列的存取。
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 * top, QNode * rear){
if(top->next==NULL){
printf("队列为空");
return rear;
}
QNode * p=top->next;
printf("%d",p->data);
top->next=p->next;
if(rear==p){
rear=top;
}
free(p);
}
#include <stdio.h>
#include <stdlib.h>
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;
}
QNode * deQueue(QNode * top, QNode * rear){
if(top->next==NULL){
printf("\n队列已空");
return rear;
}
QNode * p=top->next;
printf("%d",p->data);
top->next=p->next;
if(rear==p){
rear=top;
}
free(p);
return rear;
}
int main(){
QNode * queue,* top, *rear;
queue=top=rear=initQueue();
rear=enQueue(rear,1);
rear=enQueue(rear,2);
rear=enQueue(rear,3);
rear=enQueue(rear,4);
rear=deQueue(top,rear);
rear=deQueue(top,rear);
rear=deQueue(top,rear);
rear=deQueue(top,rear);
rear=deQueue(top,rear);
return 0;
}