c++报告 类 循环队列.docx
《c++报告 类 循环队列.docx》由会员分享,可在线阅读,更多相关《c++报告 类 循环队列.docx(14页珍藏版)》请在冰豆网上搜索。
c++报告类循环队列
《面向对象程序设计》
实验报告
姓名:
XXXXXX
学号:
U200915194
班级:
0911
专业:
计算机科学与技术
报告日期:
2011/01/05
一、实验题目
给出类的定义classQUEUE{
int*constqueue;//用于存放队列元素
intfront,rear;//队列的首指针front,尾指针rear
constintsize;//size为队列长度
public:
virtualintoperator<<(inte);//将元素e加入队列尾部
virtualintoperator>>(int&e);//从队列首部取出一个元素
virtualQUEUE&operator=(constQUEUE&q);
QUEUE(intsize);//size为队列长度
voiddisplay();//为方便于测试,添加此函数,用于显示队列元素
virtual~QUEUE();
};
二、程序设计思路
size-1
由于类(队列)的数据成员包括对长度size,而且size定义为const类型,为方便处理,可以按照循环队列的方式来实现。
①front和rear初始值定义为-1,每次插入元素时,先rear+1,再将元素插到队尾,则元素queue[i]下标取值范围为0~size-1;每次取出元素时,先front+1,再从队头取出元素。
②但是容易发现,如果不做特殊处理,队列为空和队列为满的条件一样,都是front=rear。
对于这个问题,可以这样解决,少用一个元素空间,约定以“队列头指针在队列为指针的下一位置上”作为队列“满”状态的标志。
于是队列为空的条件是front=rear,而队列为满的条件是当front<=0时rear=(size-1),或者rear+1=front。
0
queue.rear
queue.front
三、类的实现
/*构造函数,完成各数据成员的初始化。
对于常量类型数据成员size和queue,必须在构造函数之前完成初始化,而普通数据成员front和rear,可以在构造函数之前或构造函数内部初始化。
*/
QUEUE:
:
QUEUE(intsize):
front(-1),rear(-1),size(size),queue(newint[size])
{
}
/*将元素e加入队列尾部,插入成功则返回1,否则返回0。
①插入元素前,要先判断队列是否已满,若满了,则直接返回0;否则,插入元素e,并返回1。
②由于是循环队列,当rear增加到size时,就要从0开始。
③虚函数定义时,不能带virtual关键字。
*/
intQUEUE:
:
operator<<(inte){
if(((rear==(size-1))&&front<=0)||(rear+1==front))//队列已满
return0;
else
{
rear++;
if(rear==size)//rear增加到size时,就要从0开始
rear=0;
queue[rear]=e;
return1;
}
}
/*从队列首部取出一个元素,并有e带回。
取出成功则返回1,否则返回0。
①在取出元素之前,要判断队列是否为空,若为空,则直接返回0;否则,从队列首部取出元素赋给e,并返回1。
②同样,当front增加到size时,就要从0开始。
*/
intQUEUE:
:
operator>>(int&e)
{
if(front==rear)//队列为空
return0;
else
{
front++;
if(front==size)//front增加到size时,就要从0开始
front=0;
e=queue[front];
return1;
}
}
/*深拷贝函数,将形参对象q赋给当前对象。
①若q队列的长度(容量)小于当前队列的长度,则直接将头指针、尾指针、以及所有元素都复制过来。
②否则,若q队列的实际长度小于当前队列的长度(容量),则只将所有元素复制过来。
③若上2中情况都不是,则提示“不能复制”。
*/
QUEUE&QUEUE:
:
operator=(constQUEUE&q)
{
intlen2,i;
if(q.size<=this->size)
{
front=q.front;
rear=q.rear;
for(i=front;i!
=rear;)
{
i++;
if(i==size)
i=0;
queue[i]=q.queue[i];
}
}
else
{/*len2为q队列实际长度*/
if(q.rear>=q.front)
len2=q.rear-q.front;
else
len2=q.size-(q.front-q.rear);
if(this->size>=len2)
{
for(i=q.front;i!
=q.rear;)
{
i++;
if(i==q.size)
i=0;
queue[++rear]=q.queue[i];
}
}
else
cout<<"元素个数为"<size<<"的队列中!
\n";
}
return*this;/*返回当前对象*/
}
/*显示队列中所有元素。
先要判断队列是否为空,只有当队列非空时,才遍历队列,显示所有元素。
*/
voidQUEUE:
:
display()
{
if(front==rear)
cout<<"队列为空,无元素可输出!
\n";
else
{
for(inti=front;i!
=rear;)
{
i++;
if(i==size)
i=0;
cout<<"queue["<
}
}
}
/*析构函数,释放类申请的内存空间。
①为防止对同一个对象反复析构,设置析构标志,即每次析构之后,将queue置0,而每次析构之前判断一下queue是否为0,只有当queue非0时才析构。
②由于queue是常量指针,需要用*(int**)(&queue)=0赋值,而不能简单的二次赋值,否则编译报错。
*/
QUEUE:
:
~QUEUE()
{
if(queue)
{
delete[]queue;
*(int**)(&queue)=0;
}
}
/*main()函数用于测试类的功能。
*/
voidmain()
{
intchoice,e1,e2;
QUEUEq1(5),q2(3);/*定义队列q1,q2*/
do
{
cout<<"1--插入元素2--取出元素0--退出选择\n";
cout<<"选择:
";
cin>>choice;
switch(choice)
{
case1:
{
cout<<"插入元素e=";
cin>>e1;
if((q1<cout<<"队列已满,插入不成功!
\n";
break;
}
case2:
{
if(q1>>e2)
cout<<"取出元素e="<else
cout<<"队列为空,无元素可取出!
\n";
break;
}
case0:
{
break;
}
default:
{
cout<<"选择错误!
\n";
}
}
}while(0!
=choice);
cout<<"q1:
\n";
q1.display();
q2=q1;/*将队列q1拷贝到q2中*/
cout<<"q2:
\n";
q2.display();
}
四、测试结果(运行时首先会提示选择“1--插入元素2--取出元素0--退出选择”,退出选择后,则依次显示队列q1、q2的所有元素。
)
测试一(此时定义q1、q2语句为“QUEUEq1(5),q2(5);”,即q1、q2容量相同时)
①先在队列q1中顺序插入5个元素0、9、8、7、6;
②再从队列q1取出一个元素;
③最后退出选择,输出队列q1、q2中的元素。
测试二(此时定义q1、q2语句为“QUEUEq1(5),q2(3);”,即q2容量小于q1时)
1先在队列q1中顺序插入5个元素6、7、8、9、0;
2再从q1中取出3个元素;
3最后再插入元素10,之后退出选择,输出队列q1、q2元素。
五、实验体会
六、源码
#include
classQUEUE{
int*constqueue;//用于存放队列元素
intfront,rear;//队列的首指针front,尾指针rear
constintsize;//size为队列长度
public:
virtualintoperator<<(inte);//将元素e加入队列尾部
virtualintoperator>>(int&e);//从队列首部取出一个元素
virtualQUEUE&operator=(constQUEUE&q);
voiddisplay();
QUEUE(intsize);//size为队列长度
virtual~QUEUE();
};//定义的类也相当于一种数据类型,与定义变量一样,末尾要有分号
QUEUE:
:
QUEUE(intsize):
front(-1),rear(-1),size(size),queue(newint[size])//按照范围从小到大的顺序,形参的范围更小,所以替换的就是恒等式
{
}
intQUEUE:
:
operator<<(inte)
{
if(((rear==(size-1))&&front<=0)||(rear+1==front))//队列已满
return0;
else
{
rear++;
if(rear==size)
rear=0;
queue[rear]=e;
return1;
}
}
intQUEUE:
:
operator>>(int&e)
{
if(front==rear)//队列为空
return0;
else
{
front++;
if(front==size)
front=0;
e=queue[front];
return1;
}
}
QUEUE&QUEUE:
:
operator=(constQUEUE&q)
{
intlen2,i;
if(q.size<=this->size)
{
front=q.front;
rear=q.rear;
for(i=front;i!
=rear;)
{
i++;
if(i==size)
i=0;
queue[i]=q.queue[i];
}
}
else
{
if(q.rear>=q.front)
len2=q.rear-q.front;
else
len2=q.size-(q.front-q.rear);
//cout<<"长度="<if(this->size>=len2)
{
for(i=q.front;i!
=q.rear;)
{
i++;
if(i==q.size)
i=0;
queue[++rear]=q.queue[i];
}
}
else
cout<<"元素个数为"<size<<"的队列中!
\n";
}
return*this;
}
voidQUEUE:
:
display()
{
if(front==rear)
cout<<"队列为空,无元素可输出!
\n";
else
{
for(inti=front;i!
=rear;)
{
i++;
if(i==size)
i=0;
cout<<"queue["<
}
}
}
QUEUE:
:
~QUEUE()
{
if(queue)
{
delete[]queue;
*(int**)(&queue)=0;
}
}
voidmain()
{
intchoice,e1,e2;
QUEUEq1(5),q2(5);
do
{
cout<<"1--插入元素2--取出元素0--退出选择\n";
cout<<"选择:
";
cin>>choice;
switch(choice)
{
case1:
{
cout<<"插入元素e=";
cin>>e1;
if((q1<cout<<"队列已满,插入不成功!
\n";
break;
}
case2:
{
if(q1>>e2)
cout<<"取出元素e="<else
cout<<"队列为空,无元素可取出!
\n";
break;
}
case0:
{
break;
}
default:
{
cout<<"选择错误!
\n";
}
}
}while(0!
=choice);
cout<<"q1:
\n";
q1.display();
q2=q1;
cout<<"q2:
\n";
q2.display();
}