实验四队列的基本操作的实现(必做,设计性实验)
- 实验目的
熟练掌握队列的抽象数据类型,能在相应的应用问题中正确选用它,熟练掌握队列的实现方法(顺序和链式),两种存储结构和基本操作的实现算法,注意空和满的判断条件及它们的描述方法,掌握循环队列与其它顺序结构实现上的不同及解决办法,熟悉各种队列的基本操作在循环队列上的实现
- 实验内容
用队列实现形如a+b@b+a#的中心对称的字符序列的检验
选择合适的存储结构(循环队列)表示队列,解决队空、队满判断条件相同的矛盾,实现基于循环队列的存储结构的基本操作,初始化、队空/满判断,入队、出队、取队头元素、求队列长度等,对所写出的算法进行时间复杂度分析
- 数据结构定义
(说明你算法中用到的数据结构、数据类型的定义)
数据结构:用到的数据结构是循环队列,只允许一端进行插入,另一端进行删除元素,具有先进先出的特点。选择的存储结构是顺序存储结构
数据类型:base用来存储初始化的动态分配的存储空间的地址,front指向队列的第一个元素
rear指向队列的最后一个元素的下一个元素,队列类型名定义为SqQueue
typedef struct{
QElemType *base; //初始化的动态分配的存储空间
int front;//指向队列的第一个元素
int rear;//指向队列的最后一个元素的下一个元素
}SqQueue;
- 算法思想及算法设计
(先文字说明算法的思想,然后给出类C语言算法)
(1)算法的思想
①首先,需要定义一个队列来存储字符,可以使用循环队列来实现,并使用两个变量来记录队列的首尾位置;②其次,在函数中,可以遍历字符序列,并将除中心标志字符@和字符序列结束标志#之外的字符压入队列。④然后,在队列中分别取出队头字符和队尾字符进行比较,如果两个字符不同,则序列不是中心对称的,如果两个字符相同,则继续比较下一个字符,直到队列长度变为零,则字符序列是中心对称的。
(2)类C语言算法
Status Match(char*a){
p = a; //把字符串数组的首地址赋给p
flag_1=1,flag_2=1
InitQueue(&Q); //初始化队列Q
while(*p != '@') { //p当前所指的元素值不是对称中心字符的标记
EnQueue(&Q, *p); p++; //让p所指的字符进队列并使p指针指向下一个字符
}
p++; //跳过对称中心标志@,不让他进队列
while(*p != '#') { //p当前所指的字符不是队尾结束
EnQueue(&Q, *p); p++;//继续进队列
}
while (QueueLength(Q) != 0) {//队列不为空,从队尾队头分别删除字符进行比较
if (!DeQueue(&Q, &b)) flag_1=0;//取出队头元素并检查是否能取成功
if (!DeQueue_rear(&Q, &c)) flag_2=0;//取出队尾元素并检查是否能取成功
if((flag_1==0&&flag_2!=0)||(flag_1!=0&&flag_2==0))printf("不是中心对称字符序列!\n");
//队长不为零,取队头元素和队尾元素比较
else if (flag_1&&flag_2&&b != c) {//如果检测出有一对队头与队尾字符不匹配,就证明这个字符串不是中心对称
printf("不是中心对称字符序列!\n"); return FALSE;
}
else if (Q.rear == Q.front) {//当从队头队尾删除字符的两个指针相遇时,说明他们之前的字符都成功匹配上
printf("是中心对称字符序列!"); return OK;
}
flag_1=1,flag_2=1;
}
}
- 实验代码
(即C语言程序)
详见电子版
- 算法测试结果
(说明测试数据,粘贴实验结果图)
左右字符数相同,且是中心对称
左右字符数相同,且不是中心对称
左右字符数不同
- 分析与总结
(1)算法复杂度分析及优、缺点分析
(说明你编写算法的复杂度,算法的优点和缺点有哪些)
算法复杂度分析:
InitQueue(SqQueue *Q), EnQueue(SqQueue *Q, QElemType e),
DeQueue(SqQueue *Q, QElemType *e), DeQueue_rear(SqQueue *Q, QElemType *e),
QueueEmpty(SqQueue Q), QueueLength(SqQueue Q)
算法的时间复杂度为O(1)
Match(char*a)
算法的时间复杂度为O(n)
优点:
①队列提供了先进先出的特性,适用于按顺序处理字符序列的算法。
②使用队列可以轻松实现将字符按顺序插入和删除的操作。
③通过使用队列,可以直观地模拟字符序列的处理过程,便于理解和调试代码。
④队列可以灵活地扩展,适用于不同规模和复杂度的字符序列检验。
缺点:
①在实现中心对称字符序列的检验算法时,可能需要占用较大额外的内存空间来存储队列元素,对于大规模字符序列来说,可能会导致内存开销较大。
②使用队列实现算法,需要维护队列的状态,增加了算法实现的复杂度。
(2)实验总结
(说明你怎么解决实验中遇到的问题,有什么收获)
问题:
①如何判断字符序列是否为中心对称。
解决办法:可以通过遍历队列的中心标志@的前半部分和后半部分的字符同时进行比较来判断是否对称。如果不对称,即可确定序列不是中心对称的。
②在检验算法中,可能会遇到特殊字符(如@、#)。
解决办法:在实现算法时,可以通过设置条件语句来处理特殊字符的情况,对于中心标志@采取不让其进队列的操作,读到#时结束循环。
收获:
①我能够熟练掌握栈和队列的抽象数据类型,能在相应的应用问题中正确选用它们,熟练掌握队列的实现方法(顺序和链式),两种存储结构和基本操作的实现算法,注意空和满的判断条件及它们的描述方法,掌握循环队列与其它顺序结构实现上的不同及解决办法,熟悉各种队列的基本操作在循环队列上的实现。
②锻炼了处理字符串算法的能力,包括字符序列的遍历、判断和比较等操作。
③学会了通过细致的设计和处理对特殊情况的考虑,提高了编程的准确性。
④提高了对算法思路的分析和实现能力,并通过实验验证算法的正确性和效果。