钟海清

导航

03--栈和队列

1.本周学习总结

    栈和队列的学习还是比较好理解的,就是实际写起代码来困难。通过老师上课展示的源代码,在做pta时照着葫芦画瓢,稍微能有一些理解。这周收获最大的就是知道删除栈和队列元素之后需要返回栈顶和对头元素,不然会出现异常访问的情况。在利用队列进行操作的过程中,注意入队的时候判断有没有空来决定要不要修改头指针,出队时则增设一个条件判断是否为最后一个节点,然后单独处理。利用循环链队列的时候,则特别要注意最后要将头指针和尾指针的关系用next建立起来,循序循环队列则要注意在进行出入队操作时,首尾指针做相应的加减运算后应当对MaxSize取余,保证不出现**假溢出**的情况。
    栈在符号配对问题上学会了用容器和string来做,可以直接调用库函数pop,push,top来进行出栈,进栈,返回栈顶操作,调用empty函数判断栈有没有为空,为空则返回true,相当方便,就是还不太熟练。
    队列的容器操作则和栈的有些不同,在做银行队列模拟的时候,最大的收获就是知道队列的容器front和pop的区别,front函数返回的是队头元素,pop函数只是将队头元素弹出,不返回任何值。还有一个附加功能就是函数back() 返回最后被压入的元素(队尾元素),如果需要逆序输出队列元素的时候可以用到。
    本次上机考一开始是比较开心的,循环队列,另类堆栈还有符号配对都是原题,过了第一题另类堆栈后就不顺利了,另外两题一直改不出错误,直到出了考场才发现原来是一些细节问题。可能考前太过于自信吧,觉得自己只要知道思路就好了,其他不用管,但偏偏细节决定成败。而且,我总觉得自己学习方法出了问题,努力和结果不成正比,应该是没理解到题目或对自己太过相信了吧。。。

2.PTA实验作业

2.1.题目1:在一个数组中实现两个堆栈

2.1.1代码截图


2.1.2本题PTA提交列表说明。

  • Q1:一开始提交就出现了输出超限这个错误
  • A1:经同学指点才明白过来共享栈是不可以将两个栈顶都置为-1的,另一个应该为Maxsize,然后依次向中间靠近
  • Q2:当时在vs上运行正确后交上去仍是答案错误,表示非常不解
    vs运行结果

    pta测试结果
  • A2:在pop函数中,应该先返回栈顶元素再S->Top做相应的加减,此处可能是vs测试不够严格导致没有发现错误

2.2 题目2:舞伴问题

假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队。跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。 你需要用队列操作实现上述算法。请完成下面5个函数的操作。

2.2.1代码截图

2.2.2PTA提交列表说明

  • Q1:一开始的编译错误是忘记该题为函数题,直接将整个代码粘贴上去了

  • A1:去掉原有代码即可

  • Q2:答案错误,程序出现乱码

  • A2:一开始以为乱码是因为输出的时候类型错了导致,就一直在检查,直到对比同学代码,才发现应该在出队列DeQueue这个函数中将front指针将自增再返回结果,因为后面函数要返回数给X,所以应该放在前面。

  • 此题的话代码难点不多,就是函数之间的包含关系,舞伴配对那个函数包含了所有函数的调用,只要弄清楚他们之间的关系,还是比较好做。一开始以为队列Q是先存所有的dancer然后再根据性别分别放入队列。后面发现可以不用这么复杂,直接进队就好,Q只是一个函数定义需要用到的变量

2.3 题目3:判断字符串是否对称

编写一个算法利用顺序栈判断一个字符串是否是对称串。所谓对称串是指从左向右读和从右向左读的序列相同。

2.3.1设计思路

  • 利用栈来存储字符串
  • 计算字符串长度
  • 利用循环遍历到长度的1/2
    • 将字符串前半部分入栈
  • 判断字符串长度是奇数的话,就除2加一,存到变量 j 里面,以便循环一半
  • 循环从上一步的 j 到最后length为止
    • if碰到栈顶元素和字符串后半部分不相等,就输出no并返回
    • 否则栈顶指针下移,继续找
  • 最后循环未输出no,则字符串是对称的
  • 这题利用栈先进后出的特点来判断字符串是否对称

2.3.2代码截图

2.3.3PTA提交列表说明

  • A1:一开始的编译错误是在输入#include的时候不小心多输了一个空格,导致编译错误,错误提示如下

    -Q2:在编译器上调试的时候,计算字符串line长度发生错误
    -A2:将sizeof改为strlen就可以了

2.4 题目4:银行业务队列简单模拟

设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

2.4.1设计思路

  • 利用容器来存储队列元素,函数调用什么的更加方便好用
  • 先循环输入号码,对2取余,如果是奇数就进A队,否则进B队,此处调用函数push(注意:push里面要有内容,否则会发生错误)
  • 先判断A队是否为空队,是就要让B队进行循环输出
    • 设置temp变量,让B队第一个出队元素前面不带空格
    • 输出B队的一个元素,用到front()函数,此时返回的是队头元素特别注意:后面还要加上pop()函数让队头元素出队,否会进入死循环
    • 最后return 0,不再进行后面语句
  • A队不为空的话,则先设置一个flag变量控制第一个元素前不带空格
    • 第一个元素出队后还要判断此时A队有没有空才可以继续,不空第二个元素出队才合法
    • 然后if判断B不为空就可以出队
    • 此时让flag=0,使下次循环输出的第一个A队元素前面带空格
  • 出现B队比A队长的情况,此时B队就未空,还要一个循环逐个让B中元素出队

2.4.2代码截图


2.4.3PTA提交列表说明

  • Q1:一开始输出的元素是9个,而且乱码
  • A1:在一开始A中第一个元素出队时没有加上pop函数,导致多输出一个
  • Q2:前4个号码正确,后面4个乱码
  • A2:这个时候我一直检查后面的逻辑问题,却发现是在一开始将数字用数组存储时,for循环本身i++了,我循环里面又让i++导致第四到第八个数组位置没有存入数字,删掉即可
  • A3:后面发现可以不用数组,直接边输入边判断是奇数还是偶数,然后入队,这样降低了空间复杂度

3、栈和队列上机考试

错题1:另类循环队列

如果用一个循环数组表示队列,并且只设队列头指针Front,不设尾指针Rear,而是另设Count记录队列中元素个数。请编写算法实现队列的入队和出队操作。

错误代码:

正确代码:

解决办法:

  • Q1:一开始没有认真审题,以为是顺序队列,然后写的代码就错误

  • A1:改为循环队列,首尾指针加减后对MaxSize取余

  • Q2:上诉交上去仍是答案错误,无限循环

  • A2:把Q->Count当成了尾指针,导致后面的while(Q->Count)循环出不来,经修改后即可(此处特别注意循环队列队头队尾以及Maxsize的关系

  • 在审题的时候还是要仔细,这题在考前没有做,是临场发挥,比较不熟悉。对循环队列的首尾指针移动时需要对MaxSize取余不是很理解

错题2:符号配对

假设表达式中允许包含3种括号:圆括号、方括号和大括号。即(,[,'{'。编写一个算法判断表达式中的括号是否正确配对, 要求利用栈的结构实现。

错误代码:

正确代码:

解决办法

  • Q :测试点都不正确,([1+2])输出的是no

  • A1:find函数未找到返回的是-1,所以if判断条件应该为!=-1,当时忘记了这个知识点

  • A2:栈不为空没有右符号与之配对的情况下应该要输出栈顶元素并换行输出no,加上换行符即可

  • A3:符号匹配时,应该
    改为
    匹配是找左符号中对应右符号的位置下的符号和栈顶元素是不是相同,而不是直接在左符号中找符号

  • 这题在考前是做过的,按照老师的方法用容器存储符号,调用find,empty等库函数来写非常方便,就是在考试的时候,可能也是时间比较紧,写的代码在判断条件时像未找到符号应该返回的是-1忘记了,一时间又急于找自己的逻辑错误,导致这题失分严重,终归还是自己没有理解透这个题目,多练习几次就好了

posted on 2019-04-21 21:14  haiqingz  阅读(379)  评论(0编辑  收藏  举报