队列有两种存储表示,顺序表示和链式表示。
和顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,尚需附设两个整型变量front和rear分别指向队列头元素和队列尾元素的位置(即称为头指针和尾指针)。
为了在C语言中描述方便起见,在此约定:初始化创建空队列时,令front=rear=0,每当插入新的队列尾元素时,尾指针rear增1:每当删除队列头元素时,头指针front增1。因此,在非空队列中,头指针始终指向队列头元素,而尾指针始终指向队列尾元素的下一个位置,详情如下图所示
假设当前队列分配的最大空间为6,则当队列处于图3.12(d)所示的状态时不可再继续插入新的队尾元素,否则会出现溢出现象,即因数组越界而导致程序的非法操作错误。事实上,此时队列的实际可用内存并未占满:所以这种现象称为“假溢出”。这是由“队尾入队,对头出队”这种受限制的操作造成的。
一个较好的办法就是使顺序队列逻辑上称为一个环状的空间,称之为循环队列。
循环队列的思想就是使它首尾逻辑相连,可以有多种写法。重要在于
队列满时有哪几种情况。
头尾指针应如何变化以确保不溢出和正确指向。
等…
C++代码
#include<iostream>
#define MAX 5
using namespace std;
typedef struct
{
int *base;//存储空间基地址
int front;//头指针
int rear;//尾指针
}Sqqueue;
bool initqueue(Sqqueue &q)
{
q.base = new int[MAX];
if(!q.base)
return false;
q.front = q.rear = 0;
for( int i=0; i<MAX; i++ )
q.base[i] = 0;
return true;
}
void input(Sqqueue &q,int num)
{
int data;
//判断队列已满条件,一种是front****rear,头指针在开始位置,尾指针在最后位置,该队列满!
// 另一种是**front/rear*** ,头尾指针指向同一位置,且位置的两边都存有元素!
if(( q.front == (q.rear+1)%MAX && q.base[q.rear]!=0 )|| ( q.front==q.rear && q.base[0]!=0 && q.base[MAX-1]!=0 ) )
{
cout<<"队列已满,无法再存!" <<endl<<endl;
return;
}
for( int i=0; i<num; i++ )
{
cin>>data;
q.base[q.rear] = data;
cout<<"第"<<i+1<<"个入队的元素为 "<<data<<endl;
if( ( q.front == (q.rear+1)%MAX && q.base[q.rear]!=0 ) || ( q.front==q.rear && q.base[0]!=0 && q.base[4]!=0 ) )
{
cout<<"队列已满,无法再存!" <<endl<<endl;
return;
}
q.rear = (q.rear+1)%MAX;
}
cout<<endl;
}
void output(Sqqueue &q,int num)
{
for( int i=0; i<num; i++ )
{
if(q.base[q.front]==0)
{
cout<<"已没有元素可出队!"<<endl<<endl;
break;
}
cout<<"第"<<i+1<<"个出队的元素为 "<<q.base[q.front]<<endl;
q.base[q.front] = 0;
q.front = (q.front+1)%MAX;
}
cout<<endl;
if( (( q.rear+1)%MAX==0 && q.base[q.rear]!=0) || q.base[q.rear]!=0 )//当尾指针指向最后一个地址空间且已存入数据时,尾指针回到开始位置,即队列的循环性
q.rear = ( q.rear+1)%MAX;
}
int main()
{
int num;
string s;
Sqqueue q;
initqueue(q);
while( true )
{
cout<<"***你想要执行的操作(in/out *)及个数***"<<endl;
cin>>s>>num;
if( s=="in" )
input(q,num);
else if( s=="out" )
{
cout<<"\n出队列(先进先出)顺序如下(顺序存储结构)\n\n";
output(q,num);
}
}
}
结果
***你想要执行的操作(in/out *)及个数***
in 4
1
第1个入队的元素为 1
2
第2个入队的元素为 2
3
第3个入队的元素为 3
4
第4个入队的元素为 4
***你想要执行的操作(in/out *)及个数***
out 5
出队列(先进先出)顺序如下(顺序存储结构)
第1个出队的元素为 1
第2个出队的元素为 2
第3个出队的元素为 3
第4个出队的元素为 4
已没有元素可出队!
***你想要执行的操作(in/out *)及个数***
in 3
5
第1个入队的元素为 5
6
第2个入队的元素为 6
7
第3个入队的元素为 7
***你想要执行的操作(in/out *)及个数***
in 3
1
第1个入队的元素为 1
8
第2个入队的元素为 8
队列已满,无法再存!
***你想要执行的操作(in/out *)及个数***
in 1
队列已满,无法再存!
***你想要执行的操作(in/out *)及个数***
out 3
出队列(先进先出)顺序如下(顺序存储结构)
第1个出队的元素为 5
第2个出队的元素为 6
第3个出队的元素为 7
***你想要执行的操作(in/out *)及个数***
in 1
5
第1个入队的元素为 5
***你想要执行的操作(in/out *)及个数***
out 5
出队列(先进先出)顺序如下(顺序存储结构)
第1个出队的元素为 1
第2个出队的元素为 8
第3个出队的元素为 5
已没有元素可出队!
***你想要执行的操作(in/out *)及个数***
代码只是简单实现循环顺序队列的基本思想
代码中注释写得不多,如有问题可以评论留言,我会回复的,欢迎各位大佬的指导
转载需说明!