1、编写一个测试程序,统计并显示以下循环的迭代次数:while problemSize > 0: problemSize = problemSize // 2
以下是满足要求的 Python 代码:
problemSize = int(input('请输入问题规模: '))
iterations = 0
while problemSize > 0:
problemSize = problemSize // 2
iterations += 1
print('迭代次数为:', iterations)
这段代码首先让用户输入问题规模,然后通过一个 while
循环不断将 problemSize
除以 2 并统计迭代次数,最后输出迭代次数。
2、假设以下每个表达式都表示算法在问题规模为n时执行的操作数。指出每个算法的主导项,并使用大O符号对其进行分类。a. 2n – 4n² + 5n b. 3n² + 6 c. n³ + n² – n
- a. 主导项是 -4n²,大O表示法为O(n²)
- b. 主导项是3n²,大O表示法为O(n²)
- c. 主导项是n³,大O表示法为O(n³)
3、对于问题规模n,算法A和算法B分别执行n²和½n² + ½n条指令。哪个算法的工作量更大?是否存在特定的问题规模,使得其中一个算法的性能明显优于另一个算法?是否存在特定的问题规模,使得两个算法的工作量大致相同?
当n > 1时,算法A的工作量更大;当n = 1时,两个算法的工作量相同;当n > 1时,算法B的性能明显优于算法A;当n = 1时,两个算法的工作量大致相同。
4、假设一个列表在索引位置 0 到 9 包含值 20、44、48、55、62、66、74、88、93、99。跟踪在这个列表中使用二分查找目标值 90 时变量 left、right 和 midpoint 的值。对目标值 44 重复此操作。
对于目标值 90:
- 初始:left = 0,right = 9,midpoint = (0 + 9) // 2 = 4
- 第一次迭代:列表中间值为 62,90 > 62
- left = midpoint + 1 = 5,right = 9,midpoint = (5 + 9) // 2 = 7
- 第二次迭代:列表中间值为 88,90 > 88
- left = midpoint + 1 = 8,right = 9,midpoint = (8 + 9) // 2 = 8
- 第三次迭代:列表中间值为 93,90 < 93
- left = 8,right = midpoint - 1 = 7,此时 left > right,查找结束,未找到目标值
对于目标值 44:
- 初始:left = 0,right = 9,midpoint = (0 + 9) // 2 = 4
- 第一次迭代:列表中间值为 62,44 < 62
- left = 0,right = midpoint - 1 = 3,midpoint = (0 + 3) // 2 = 1
- 第二次迭代:列表中间值为 44,找到目标值
- left = 0,right = 3,midpoint = 1
5、通常用于在电话簿中查找条目的方法与二分查找并不完全相同,因为在使用电话簿时,你并不总是会查找子列表的中点。相反,你会根据人名姓氏首字母的字母顺序来估计目标的位置。例如,当你查找“Smith”的电话号码时,你会先查看电话簿后半部分的中间位置,而不是整个电话簿的中间位置。请提出一种对二分查找算法的修改方案,以模拟这种查找姓名列表的策略。这种修改后的算法在计算复杂度上是否比标准二分查找更好?
修改方案:在标准二分查找中,每次取中间位置
midpoint = (left + right) // 2
修改后,根据目标字符串首字母的字母顺序来估计位置。例如,可根据字母表顺序将列表大致划分为不同区域,根据目标首字母确定可能所在区域,然后在该区域内继续查找。
计算复杂度:
这种修改后的算法计算复杂度和标准二分查找一样,最坏情况复杂度仍为 $O(\log_2 n)$。因为虽然初始估计位置可能不同,但本质上还是不断将搜索范围缩小一半,和标准二分查找在复杂度上没有本质区别。
6、解释为什么插入排序在部分有序的列表上效果很好。
- 列表中已有序的项越多,插入排序的效果越好。
- 在列表已排好序的最佳情况下,插入排序的行为是线性的。
- 对于部分有序列表,插入排序在插入元素时,内循环需要移动元素的次数会减少,因为很多元素已经处于正确的位置,从而减少了算法的工作量。
- 所以插入排序在部分有序的列表上效果很好。
7、描述快速排序的策略,并解释为什么它可以将排序的时间复杂度从O(n²)降低到O(n log n)。
快速排序策略
快速排序的策略如下:
- 选择列表中点的元素作为基准;
- 对列表中的元素进行分区,将所有小于基准的元素移到基准左侧,其余元素移到右侧,基准的最终位置取决于实际元素;
- 采用分治法,对基准划分出的子列表递归地应用上述过程;
- 当遇到元素少于两个的子列表时,过程终止。
时间复杂度分析
快速排序能将排序时间复杂度从 $ O(n^2) $ 去到 $ O(n \log n)