数据结构实验报告—队列
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《算法与数据结构》课程
一、实验目的
掌握队列的存储结构及进队/出队等操作的实现。
二、实验内容及要求
1.实现队列的一种存储结构。
2.实现队列的相关操作。
3.利用队列的操作特点,借助进队与出队操作完成打印二项式系数的任务。
三、系统分析
(1)数据方面:该队列数据元素类型采用整型,在此基础上进行队列的一些基本操作,应用体现在打印二项式系数即打印杨辉三角形。
(2)功能方面:
1.进队操作:若队列不满,则将元素x进入队列。
2.出队操作:若队列不空,则退出队头元素x并由函数返回true,否则返
回false。
3.获取队头元素:若队列不为空,则函数返回true及队头元素的值,否则
返回false。
4.判断队列是否为空、判断队列是否满。
5.计算队列中元素个数:直接返回队列中元素个数。
6.清空队列内容:队头指针和队尾指针置0。
7.打印杨辉三角形前n行数字。
四、系统设计
(1)设计的主要思路
队列得基于数组得存储表示亦称为顺序队列,是利用一个一维数组作为队列元素的存储结构,并且设置两个指针front和rear,分别指示队列的队头和队尾位置。
每当添加一个新元素时,先将新元素添加到rear所指位置,再让队尾指针
rear进1。
每当退出队头元素,应当先把front所指位置元素记录下来,再让队头指针进1,指示下一队头元素位置,最后把记录下来的元素值返回。
但当队头指针front==rear,队列为空;而当rear==maxSize时,队列满,如果再加入新元素,就会产生“溢出”。
但这种“溢出”可能时假溢出,因为在数组的前端可能还有空位置。
为了能够充分地使用数组中的存储空间,把数组的前端和后端连接起来,形成一个环形表,即把存储队列元素的表从逻辑上看成一个环,成为循环队列。
循环队列的首尾相接,当队头指针front和队尾指针rear进到maxSize-1后,再前进一个位置就自动到0.这可以利用除法取余的运算实现。
(2)数据结构的设计
队列的定义是一种限定存取位置的线性表。
它只允许在表的一端插入,在另一端删除。
允许插入的一端叫做队尾,允许删除的一端叫做队头。
最先进入队列的元素最先退出队列,队列这种特性叫做先进先出。
空队列
A进队
对头指针进1:front=(front+1)%maxSize;
队尾指针进1:rear=(rear+1)%maxSize;
队列初始化:front=rear=0;
循环队列的队头指针和队尾指针初始化时都设置为0:front=rear=0.在队尾插入新元素和删除队头元素时,两个指针都按顺时针方向进1.当它们进到maxSize-1时,并不表示表的终结,只要有需要,利用%运算可以前进到数组的0号位置。
五、编程环境与实验步骤
(1)编程环境
操作系统:Windows操作系统;编程工具软件:Visual Studio 2017
(2)实验步骤
无文件操作。
(3)编译参数
无特殊的编译参数设置。
六、实现代码
主要功能的实现代码
杨辉三角函数:
void YANGVI(int n) {
Queue<int> q(n + 2);
int i = 1; int j = 0; int s = 0, k = 0; int t, u;
q.EnQueue(i); q.EnQueue(i);
for (i = 1; i <= n; i++) {
q.EnQueue(k);
for (j = 1; j <= i + 2; j++) {
q.DeQueue(t);
u = s + t;
q.EnQueue(u);
s = t;
a[0] = 1;
if (j != i + 2) {
a[o] = s; o++;
}
}
}
}
杨辉三角形输出显示函数:
void Show(int *a, int n) {
int i, j; int sum = 0; int k = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n - i - 1; j++)
cout << setw(3) << " ";//前导空格,为单个数据的一半宽度
for (j = 0; j <= i; j++) {
cout << setw(6) << a[sum + j];
k++;
}
sum = k;
cout << endl;
}
}
SeqQueue循环队列模板:
template<class T>
class Queue {
public:
Queue(int sz = 100);
~Queue() { delete[]elements; }
bool EnQueue(T &x);
bool DeQueue(T &x);
bool getFront(T &x);
void makeEmpty() { front = rear = 0; }
bool IsEmpty();
bool IsFull();
int getSize();
friend ostream& operator<<(ostream &os, Queue<T> &Q); private:
int rear, front;
T *elements;
int maxSize;
};
template<class T>
Queue<T>::Queue(int sz) {
rear = 0; front = 0;
maxSize = sz;
elements = new T[maxSize];
assert(elements != NULL);//断言:动态存储分配成功与否}
template<class T>
bool Queue<T>::EnQueue(T &x) {
if (IsFull() == true) return false;
elements[rear] = x;
rear = (rear + 1) % maxSize;
return true;
}
template<class T>
bool Queue<T>::DeQueue(T &x) {
if (IsEmpty() == true) return false;
x = elements[front];
front = (front + 1) % maxSize;
return true;
}
template<class T>
bool Queue<T>::getFront(T &x) {
if (IsEmpty() == true) return false;
x = elements[front];
return true;
}
template<class T>
bool Queue<T>::IsEmpty() {
return (front == rear) ? true : false;
}
template<class T>
bool Queue<T>::IsFull() {
return ((rear + 1) % maxSize == front) ? true : false;
}
template<class T>
int Queue<T>::getSize() {
return (rear - front + maxSize) % maxSize;
}
template<class T>
ostream& operator<<(ostream& os, Queue<T> &Q) { os << "front=" << Q.front << ",rear=" << Q.rear << endl;
for (int i = Q.front; i != Q.rear; i = (i + 1) % Q.maxSize) { os << i << ":" << Q.elements[i] << endl;
}
return os;
}
七、测试结果与说明
n为4时杨辉三角输出为:
n为10时杨辉三角输出为:
n为20时杨辉三角输出为:
八、实验分析
(1)算法的性能分析
打印杨辉三角:从三角形的形状可知,除第一行以外,在打印第i行时,用到上一行(第i-1行)的数据,在打印第i+1行时,又用到第i行的数据。
队列的操作的时间复杂度都是O(1)。
循环队列和链队列的空间性能的比较与顺序栈和链栈的空间性能比较类似,只是循环队列不能像顺序栈那样共享空间,通常不能在一个数组中存储两个循环队列。
(2)数据结构的分析
队列是另一种限定存取位置的线性表。
它只允许在表的一端插入,在另一端删除。
队列所具有的这种特性就叫做先进先出。
为了能够充分地使用数组中的空间,把数组的前端和后端连接起来,形成一个环形的表,即把存储队列元素的表从逻辑上看成一个环,成为循环队列。
适用场景:当储存数据比较大的时候适合用队列。
九、实验总结
经过几天的努力,完成了数据结构的队列的实验内容,能够熟练掌握队列的基本操作并且对于队列的应用有所了解,掌握了队列的特点即先进先出,以及进队、出队等基本操作。
并实现了队列的应用即打印二项展开式的系数。
在程序的整个分析、设计、实现、测试等环节都有所收获。
由于前面几次实验积累的经验,加上课堂上老师的相应讲解,在程序的分析阶段花费的时间主要在确定队列存储方式上,在确定使用循环队列存储元素后,又对循环队列的基本操作进行了学习,在掌握循环队列的实现后将代码编写完成后,这次实验也变得没那么困难了。
本次实验的难点就在于使用队列输出二项式系数,由于需要用队列实现所以就必须要熟练掌握循环队列的实现代码,最开始写的时候由于忽略了循环队列最多只能存储maxSize-1个元素,所以导致二项式系数输出的最后一行始终有问题,反复逐步调试了几次代码才发现了问题所在,这个过程让我印象比较深刻,对于循环队列最多存储元素个数也牢记在心。
另外在输出二项式的格式上也花费了时间,因为由于数字长度的不一样所以
在行数过大之后会导致三角形格式不那么整齐,为了解决这个问题也花费了很多时间,最后决定通过将队列操作中得到的系数存入数组中,再通过一个输出显示函数来修改输出格式使得输出的杨辉三角型呈等腰三角形。
通过此次实验,不仅在编写相关算法的能力有所提高,同时对队列的基本操作理解也相当到位,更能将队列实际应用在不同场景中,但还需要对此次实验中核心代码进行深入理解,方便日后再使用队列时更加熟练。