1.对分治法思想的体会
我在课堂学习并且多次在电脑上尝试后知道了分治法以及其高效实用,在上学期数据结构的学习中就已经接触了这种算法思想,比如二分搜索算法,快排算法和归并排序算法,只是当时没有特别深的感触,也不知道这就是分治思想。
分治法,英文名Divide and Conquer,主要有三步。
课本上分治法的一般设计模式:
divide-and-conquer(P) { if(|P| <= n0) adoc(P); divide P into smaller subinstances P1, P2, ..., Pk; for(i = 1; i <= k; i++) yi = divide-and-conquer(Pi); return merge(y1, y2, ..., yk); }
分治法三“步”曲:
第一步,分,即将规模较大的问题分解成规模较小、互相独立且与原问题相同的子问题,子问题相互独立与否会影响到算法的效率高低;
第二步,治,解决子问题,若子问题仍然不够小,则回到第一步在将子问题分解,递归解决,直到解决;
第三步,合,将各子问题的解合并得到原问题的解,这一步也是分治法是否成功的关键。
就好比,要拼一个巨大的积木房子 ,我可以先把门,围墙,窗户,草地分别拼好后,再把这些部件组合在一起
以归并排序为例,归并算法从局部出发,将元素分组,成为大小大致相同的两个子集合,对两个子集合进行排序,递归调用,子集从最开始一个元素到两个,到三或四个......一直到最后得到排好序的原来的大小。时间复杂度为O(nlogn)。一下是课本中的伪代码
void MergeSort(Type a[], int left, int right) { if (left < right) //至少两个元素 { int i = (left + right) / 2; //取中点 MergeSort(a, left, i); MergeSort(a, i+1, right); Merge(a, b, left, i, right); //合并 copy(a, b, left, right); //复制回数组a } }
快速排序相反,由大的出发开始划分,逐渐缩小排序范围,但同样用了分治思想。平均时间复杂度为O(nlogn)。当然,由于快排算法每次划分的对称性不能保证,最坏的情况下时间复杂度会达到O(n2)。
2.结对编程情况汇报
在上机实验的课上,我的搭档主负责第一题,第二题我写但是与第一题思路差不多就直接沿用了第一题的代码,而我负责第三题。编程过程中,在探讨完思路后,一个人敲代码时另一人就负责找bug,开始时效率还算ok。但是由于我们的编程习惯不同,在代码的格式上差异不小。最后我写第三题时,一开始时间复杂度过高不符合要求,在参考网上资料并讨论之后仍有疑惑,到课的最后总算弄懂了却没时间写了,回来后才把第三题写完。由于合作时间不长所以还不算默契,但可以与搭档分享不同的见解,找出更好的方法,确实地提高了编程效率,也算是个好的开头吧。