引言:在上次复习栈的基本操作后,这一次我们来复习队列的相关知识与操作。至此——我们开始数据结构队列的学习。
一.队列的定义
在栈的学习中,我们知道栈是一种只能在一端进行操作的数据结构。而队列,是一种可以在两端进行操作的数据结构,是先进先出的操作顺序。
定义:在一端进行插入操作,在另一端进行删除操作。
二.队列的基本操作
1.顺序队列
顺序表达
既然我们知道了队列是两端操作,所以我们定义两个指针用来表达数据。
struct queue//定义队列
{
int data[Max];//数据域
int front;//头指针
int rear;//尾指针
};
同理,以上的是最基本的实现,其他操作要看需求。
顺序插入
void In_queue(struct queue *p,int k)
{
if(p->rear==Max)
exit(0);
p->data[p->rear]=k;
p->rear++;//让尾指针进行加操作,用于后续数据的插入
}
顺序输出
int Out_queue(struct queue *q)
{
int e;
if(q->front==Max)
exit(0);
e=q->data[q->front];
q->front++;//头指针进行操作,让队列达到先进先出的要求
return e;
}
现在我们来看一下完整代码:
#include <iostream>
using namespace std;
#define Max 103
struct queue
{
int data[Max];
int front;
int rear;
};
void In_queue(struct queue *p,int k)//插入
{
if(p->rear==Max)
exit(0);
p->data[p->rear]=k;
p->rear++;
}
int Out_queue(struct queue *q)//输出
{
int e;
if(q->front==Max)
exit(0);
e=q->data[q->front];
q->front++;
return e;
}
int main()
{
int n,m,j,k,l,i;
struct queue list;
list.front=0;
list.rear=0;
cin>>n;
for(i=0;i<n;i++)
{
cin>>m;
In_queue(&list,m);
}
for(i=0;i<n;i++)
{
l=Out_queue(&list);
cout<<l<<" ";
}
return 0;
}
2.循环队列
在我们学习的队列的基本使用后,我们来思考,在输出时,front指针时加一的。所以队列在使用后就会有一部分不在重用。所以,我们考虑循环队列
如果我们将数组的首尾相接,那么我们就创立了循环队列。这时,队列长度满足(rear-front+Max)%Max。
我们来看下代码
循环表达
struct queue//和普同的队列是一样,但是其他操作不同
{
int data[103];
int front;
int rear;
};
循环插入
void In_queue(struct queue *p,int k)
{
if((p->rear+1)%Max==p->front)//判断队列是否满
exit(0);
p->data[p->rear]=k;
p->rear=(p->rear+1)%Max;//指针后移到下一位
}
循环输出
int Out_queue(struct queue *q)
{
int e;
if(q->front==q->rear)//判断队列是否为空
exit(0);
e=q->data[q->front];
q->front=(q->front+1)%Max;//指针后移到下一位
return e;
}
现在我们来看完整代码:
#include <iostream>
using namespace std;
#define Max 103
struct queue
{
int data[103];
int front;
int rear;
};
void In_queue(struct queue *p,int k)//插入
{
if((p->rear+1)%Max==p->front)
exit(0);
p->data[p->rear]=k;
p->rear=(p->rear+1)%Max;
}
int Out_queue(struct queue *q)//输出
{
int e;
if(q->front==q->rear)
exit(0);
e=q->data[q->front];
q->front=(q->front+1)%Max;
return e;
}
int main()
{
int n,m,j,k,l,i;
cin>>n;
struct queue list;
list.front=0;
list.rear=0;
for(i=0;i<n;i++)
{
cin>>m;
In_queue(&list,m);
}
for(j=0;j<n;j++)
{
l=Out_queue(&list);
cout<<l<<" ";
}
return 0;
}
3.链式队列
链式队列,其实就是只能在两端操作的单链表
当然,我们这里定义头结点
链式表达
struct queue//队列节点
{
int data;
struct queue *next;
};
struct link_Q//队列的链式结构
{
struct queue *front,*rear;//首尾指针
};
链式初始化
void start_queue(struct link_Q *q)//就是初始化头结点
{
struct queue *s=new(struct queue);
s->data=0;
s->next=NULL;
q->front=s;
q->rear=s;
}
链式插入
void In_queue(struct link_Q *p,int k)
{
struct queue *s=new(struct queue);
s->data=k;
s->next=NULL;
p->rear->next=s;//这里就是链表的尾插法
p->rear=s;
}
链式输出
int out_queue(struct link_Q *L)
{
int e;
struct queue *s;
if(L->front==L->rear)//判断是否为空
exit(0);
s=L->front->next;
e=s->data;
L->front->next=s->next;//将原头结点的后续L->next赋值给头结点后续
if(L->rear==s)
L->rear=L->front;
delete(s);
return e;
}
现在我们可以写出完整代码:
#include <iostream>
using namespace std;
struct queue
{
int data;
struct queue *next;
};
struct link_Q
{
struct queue *front,*rear;
};
void start_queue(struct link_Q *q)//初始化
{
struct queue *s=new(struct queue);
s->data=0;
s->next=NULL;
q->front=s;
q->rear=s;
}
void In_queue(struct link_Q *p,int k)//插入
{
struct queue *s=new(struct queue);
s->data=k;
s->next=NULL;
p->rear->next=s;
p->rear=s;
}
int out_queue(struct link_Q *L)//输出
{
int e;
struct queue *s;
if(L->front==L->rear)
exit(0);
s=L->front->next;
e=s->data;
L->front->next=s->next;
if(L->rear==s)
L->rear=L->front;
delete(s);
return e;
}
int main()
{
int n,m,j,k,l,i;
struct link_Q list;
start_queue(&list);
cin>>n;
for(i=0;i<n;i++)
{
cin>>m;
In_queue(&list,m);
}
for(i=0;i<n;i++)
{
l=out_queue(&list);
cout<<l<<" ";
}
return 0;
}
后记
本次我们写队列的实现,其主要问题就是空间问题,所以我们实现了循环队列。但是动态空间的优势可能更符合我们的需求,所以我们又实现了链式队列。到这里,队列就结束了,我们将继续往下学习。