排序问题要重排的对象是( )。
考点:排序问题与关键字(A1)。
(A1)考点:排序 = 把一组记录按关键字的大小关系重新排列;关键字可以是整数、字符串、结构体的某个成员——凡能比大小的皆可。
解析:排序算法与"排的是什么"无关:整数、字符按码值、学生按分数,算法同一套;比的是关键字、动的是整条记录。
排除法:选"只能是整数/字母"的人把载体当成了本质;选"文件的创建日期"的人只是举了一个具体关键字,没回答"排什么"。
把数组 排成非递增顺序,结果是( )。
考点:升序与降序(A2)。
(A2)考点:非递增 = 每一步不增 = 降序(可相等相邻): 排成 9 5 2 1。
解析:题目术语三兄弟——递增(严格大于)、非递减(允许相等)、非递增(允许相等);本题"非递增"就是从大到小。
排除法:选 1 2 5 9 的人排成了升序;选 5 2 9 1 的人没排序;选 1 9 2 5 的人乱序。
排序算法"稳定"的准确含义是( )。
考点:稳定性的定义(A3)。
(A3)考点:稳定 = 关键字相等的元素排序后相对次序不变——排之前谁在前,排之后还在前。
解析:稳定性与"结果正确"无关(值序都对),只关心相等元素的先后;判断靠"相等时会不会被交换/跨越"。
排除法:选"不死循环"的人把"稳定"理解成了运行可靠;选"一样快"的人理解成了性能一致;选"结果一定正确"的人——正确性是排序的底线,不是稳定性的定义。
稳定排序在实际中最重要的用处是( )。
考点:稳定性的意义(A4)。
(A4)考点:稳定排序的价值在多关键字排序:先按次要关键字排、再按主要关键字(稳定)排——主要关键字相同者保住第一轮按次要关键字排好的次序(E8 展开)。
解析:不稳定排序第二轮会把第一轮的次序搅乱;先次后主+稳定=一次到位,这是稳定性的实战意义。
排除法:选"更快/更省空间"的人把稳定性当成了性能指标;选"结果好看"的人没抓到场景。
下列排序算法中,不通过比较元素大小完成排序的是( )。
考点:比较类与非比较类(A5)。
(A5)考点:冒泡/快排/插入都靠元素两两比较决策;计数排序靠"值当下标进桶"绕开比较——非比较类。
解析:比较类受 下界约束(I6),非比较类(计数)用值域信息换线性速度(E 组展开)。
排除法:冒泡、快排、插入全是比较排序——逐项排除即可。
"原地排序"指的是( )。
考点:原地排序(A6)。
(A6)考点:原地排序 = 只用 级额外空间、直接在原数组内交换完成;冒泡/选择/插入/快排原地,归并/计数不是。
解析:少量临时变量(如交换用的 t、下标)不算破坏原地;辅助数组才算 额外空间。
排除法:选"不能借助任何变量"的人把原地苛刻到无法实现;选"在原来的电脑上"的人望文生义;选"地址段不变"的人把说法与内存管理混淆。
评价一个排序算法,通常关注的维度不包括( )。
考点:评价排序的维度(A7)。
(A7)考点:评价排序的三大维度:时间复杂度(最好/平均/最坏)、空间复杂度(是否原地)、稳定性。代码行数不是评价指标。
解析:三维度综合看:没有全胜的算法——快排平均快但最坏退化,归并稳定但要辅助空间,选谁看场景(I7/I8)。
排除法:代码长短与算法质量无关——选它的人把可读性指标混进了算法评价。
关于排序算法家族,正确的是( )。
考点:算法家族总览(A8)。
(A8)考点:平方家族(冒泡/选择/插入)简单直接; 家族(归并、快排平均、堆排)更快更复杂;计数排序非比较、靠值域桶接近线性。
解析:三档速度对应三类思想:相邻交换/选位插入、分治与堆结构、值域统计;记忆地图先立起来,各组展开。
排除法:选"复杂度都相同"的人没分档;选"计数任何场景首选"的人忽略了值域限制(E3);选"快排最坏也 "的人混淆了平均与最坏(G5)。
冒泡排序的基本动作是( )。
考点:相邻比较交换思想(B1)。
(B1)考点:冒泡 = 从头到尾依次比较相邻两个元素、逆序即交换——每轮把当前最大值"冒"到未排序段末尾。
解析:相邻性是冒泡的身份证:只动邻居、逐轮推进;与选择的"隔空换位"对照(C 组)。
排除法:选最小换最前的是选择排序;插入前缀的是插入排序;分半合并的是归并。
对 升序冒泡,第一轮结束后的数组是( )。
考点:一轮最大沉底(B2)。
(B2)考点: 第一轮: 交换得 ; 不换; 交换——结果 3 5 1 8,最大值 沉底。
解析:一轮 = 次相邻比较;轮末未排序段的最大值必然到位于末尾,这是冒泡正确性的根基。
排除法:选 1 3 5 8 的人把整场排完了;选 3 1 5 8 的人多跑了一轮(那是两趟的结果);选原序的人没动手。
个元素的标准冒泡排序(不带提前退出优化),最多需要跑几轮内层扫描( )。
考点:趟数与整体流程(B3)。
(B3)考点:标准冒泡最多 轮内层扫描: 个元素最多 轮——每轮固定一个最大值,剩最后一个自然就位。
解析:轮数上界 而非 :排好前 个后最后一个无处可去;带提前退出时实际轮数可能更少(B6)。
排除法:选 的人多数了一轮;选 的人按 的味道乱猜;选 的人少数了(4 个逆序最多需 4 轮收缩)。
冒泡排序的平均与最坏时间复杂度是( )。
考点:时间复杂度(B4)。
(B4)考点:冒泡平均与最坏都是 :比较次数约 ,与逆序程度挂钩。
解析:最好情况要靠提前退出优化才到 (B6/B7);无优化时即使有序也跑满 次比较。
排除法:选 " 与 " 的人把它当成了快排;选 " 与 " 的人默认了带优化;选 " 与 " 的人臆造了更坏档。
冒泡排序的稳定性判断:相邻比较交换时只有严格大于才交换,因此( )。
考点:稳定性(B5)。
(B5)考点:冒泡只对严格大于的相邻对交换,相等对从不交换——相等元素的相对次序保持,冒泡稳定。
解析:稳定性判据就一句话:"相等时动不动";冒泡不动,稳定;选择会隔空换位,不稳定(C4)。
排除法:选"相等可能交换"的人没看严格大于;选"取决于数据"的人稳定性是算法性质与数据无关;选"偶数才稳定"的人无稽之谈。
带优化的冒泡每轮记下"是否发生过交换",若一整轮没有交换就提前结束。这样优化的目的是( )。
考点:提前退出优化(B6)。
(B6)考点:每轮记录是否发生过交换,一整轮无交换即整体有序、提前结束——最好情况(已序)首轮就比较 次收工;但最坏(逆序)每轮都有交换,救不了,仍是 。
解析:优化只改善好情况,不改变最坏复杂度;"无交换=有序"是冒泡的重要不变量。(2020 年真题的 FLAG 版冒泡考法)
排除法:选"最坏变 "的人高估了优化;选"比较恒为 "的人那是无优化版;选"变成稳定排序"的人把性能与稳定性混了。
对已经有序的数组 使用带提前退出优化的冒泡排序,总比较次数是( )。
考点:已序输入比较 n 减 1(B7)。
(B7)考点:已序 + 提前退出:第一轮比 次( 次)、零交换、立即结束——总比较 。
解析:这是带优化冒泡的最好情况 ;若不带优化会继续空跑到 。
排除法:选 的人按无优化算了全程;选 的人以为有序就完全不比;选 的人把两轮比较翻倍乱算。
对完全逆序的数组 冒泡排序,总比较次数是( )。
考点:逆序输入比较 n(n-1)/2(B8)。
(B8)考点:逆序 是最坏输入:每轮都有交换、优化失效,比较总数 次。
解析:完全逆序 = 每一对都比较并交换过;注意本题 时 ,与选项 (那是交换+比较混算或 的值)区分。
排除法:选 的人算成了 或把交换也计入比较;选 、选 的人都少数了轮次。
用冒泡排序对数组 升序排序,需要的元素交换次数是( )。(2025 年 CSP-J 单选真题数据)
考点:交换次数等于逆序对数(B9)。
(B9)考点:冒泡每次相邻交换恰好消除一个逆序对,总交换次数 = 数组的逆序对数: 的逆序对是 对,交换 次。(2025 年 CSP-J 单选真题数据)
解析: 共 对;归并排序能在 统计逆序对(F11),两法互证。
排除法:选 的人漏了一对(常漏 );选 的人多算;选 的人把比较当交换。
阅读程序:
01int a[4] = {5, 3, 8, 1}; 02for (int j = 0; j < 3; ++j) 03 if (a[j] > a[j + 1]) swap(a[j], a[j + 1]);
循环结束后数组是( )。
考点:一趟后的状态(B10)。
(B10)考点:程序就是冒泡第一趟: 换; 不换; 换——得 3 5 1 8。
解析:读代码逐对跟踪即可;j < 3 恰是 对相邻比较。
排除法:选 1 3 5 8 的人排到了底;选 3 1 5 8 的人多换了一步;选原序的人没执行交换。
对 升序冒泡两趟后(第二趟内层上界相应缩小),数组是( )。
考点:两趟后的状态(B11)。
(B11)考点:第二趟在 3 5 1 8 上比较前 对: 不换; 换——得 3 1 5 8,次大值 归位倒数第二。
解析:两趟后末两位 就位、前两位仍乱——冒泡从右往左逐位"凝固"。
排除法:选 1 3 5 8 的人跑完了全程;选 3 5 1 8 的人只跑了一趟;选 1 5 3 8 的人交换对象搞错。
把升序冒泡改成降序(大的在前),只需把交换条件改成( )。
考点:降序冒泡改法(B12)。
(B12)考点:降序只需把交换条件改为 a[j] < a[j + 1]——"小在前"才交换,大值浮向前。
解析:改一个比较方向就翻转整个序;用 >= 会在相等时也交换,白白破坏稳定性并多做交换。
排除法:选 != 的人相等也换、序全乱;选"多跑一趟"的人方向不变多跑也没用;选 >= 的人破坏了稳定性。
标准冒泡第 趟( 从 起)的内层循环条件是 j < n - 1 - i,其中 - i 的作用是( )。
考点:内层边界 n-i-1(B13)。
(B13)考点:第 趟后末尾 个位置已被前几趟放好最大元素,内层上界 n-1-i 让范围逐趟收缩、已就位元素不再参与。
解析:不写 - i 结果仍正确但白比较已就位段(比较次数翻倍量级不变、常数翻倍);写成 j < n-1-i 是标准紧凑写法。
排除法:选"提前结束全部循环"的人那是提前退出优化(B6);选"防负下标"的人那是内层别的防护;选"没作用"的人没看比较次数差异。
对 冒泡排序,整个过程中的交换次数与结果分别是( )。
考点:交换计数模拟(B14)。
(B14)考点: 只有一对逆序 :交换 次得 1 2 3;第二轮(若跑)无交换。
解析:小数据手模:比较 交换;比较 不换——一次交换收工。
排除法:选 次的人连不换的也算了;选 次的人没看见 逆序;选 次结果还错的人把排好的数组又动了。
选择排序每一轮做的事情是( )。
考点:选最小放最前思想(C1)。
(C1)考点:选择排序每轮在未排序区间选出最小值、与未排序区间第一个位置交换—— 轮后整体有序。
解析:选位(找最小)与换位(一次交换)分离:比较很多、交换很少——这是它与冒泡的本质分工差异。
排除法:相邻交换是冒泡;插入前缀是插入排序;分半递归是归并/快排。
对 (已有序)做选择排序,总比较次数是( )。
考点:比较次数固定(C2)。
(C2)考点:选择排序每轮完整扫描找最小,比较次数与输入无关恒为 ——已序的 也要比 次。
解析:找最小必须看全——不扫完怎么知道谁最小?有序性帮不了它;这与冒泡/插入"数据越有序越快"形成对照(I1)。
排除法:选 的人以为有序就免扫;选 、 的人都按"已序省事"的错觉少算了。
个元素的选择排序,交换次数最多是( )。
考点:交换次数至多 n-1(C3)。
(C3)考点:每轮至多一次交换(最小值换到首位), 个元素 轮——交换次数 , 个元素最多 次。
解析: 是比较次数不是交换次数——选择的"多比少换"两笔账分开记。
排除法:选 的人把比较次数当成交换次数;选 的人多算一轮;选 的人只看了某一轮。
数组 (、 值相等,下标区分身份)。选择排序第一轮把最小值 换到最前,结果是( )——这正是选择排序不稳定的现场。
考点:不稳定性实例(C4)。
(C4)考点: 第一轮最小值 与首位 隔空交换:得 2 8 5b 5a—— 被甩到 之后,相等元素次序被破坏,选择排序不稳定(2022 年真题判定项)。
解析:不稳定的根源是"远距离交换"跨越了同值元素;冒泡只动邻居所以稳定(B5)。
排除法:选"次序不变"的人没跟踪身份标记;选 2 5a 8 5b 的人交换对象找错;选"任何数组都不稳定"的人说过了头——不稳定指存在破坏次序的输入,不是每个输入都破坏。
对 做选择排序第一轮(找最小放最前),数组变为( )。
考点:一轮后最小就位(C5)。
(C5)考点: 第一轮找最小 (下标 )与首位 交换:得 1 4 3 2。
解析:只有首位置换;未排序段 内部次序保持原样(这是选择不稳定的原因之一)。
排除法:选全序的人跑完了整场;选原序的人没执行交换;选 1 3 2 4 的人把整段都动了。
变体选择排序:每轮选最大值与未排序区间最后一个位置交换。对 第一轮后数组是( )。
考点:选最大放末尾(C6)。
(C6)考点:变体"每轮选最大放末尾": 最大 (已在首位)与末位 交换——得 2 1 3。
解析:镜像变体:凝固方向从右端开始;首元素恰是最大时也要与末位交换(除非重合)。
排除法:选 1 3 2 的人以为"已在首位就不用换"——位置约定是末尾,必须换;选 1 2 3、原序的人执行错了对象。
选择排序相对冒泡排序的典型优势是( )。
考点:与冒泡对比(C7)。
(C7)考点:选择排序的招牌优势:交换次数至多 ,远少于冒泡的逐对交换——数据移动代价大的场景(如大结构体)占优;但比较次数两者同量级、选择还不吃"基本有序"的红利。
解析:冒泡多换少省心、选择多比少换位;各记一笔账(I1 汇总对比)。
排除法:选"比较更少"的人两者比较同量级;选"交换更多"的人恰好反了;选"复杂度更低"的人都是 。
对 做选择排序一轮后的数组是( )。
考点:一轮后的状态(C8)。
(C8)考点: 第一轮最小 (下标 )与首位 交换:得 1 2 8 5。
解析:注意 恰好在正确位置附近但没被动过——选择只保证"最小就位",不管其他元素的次序。
排除法:选 2 5 8 1 的人交换成相邻对换了;选 1 5 8 2 的人把 放错了位;选全序的人跑完了全程。
对 做完整选择排序,结果是( )。
考点:排序结果模拟(C9)。
(C9)考点: 完整选择排序的最终结果当然是 1 2 5 8。
解析:任何正确的排序算法结果都相同——差异全在过程与开销;本题顺手验证模拟熟练度。
排除法:选 5 8 2 1 的人排成降序;1 2 8 5 是只跑一轮的中间态;2 1 5 8 的人过程混乱。
对 做完整选择排序,总交换次数是( )。
考点:交换次数模拟(C10)。
(C10)考点: 选择排序:轮 换 ;轮 换 (最小 );轮 最小 已位不换——共 次。
解析:交换计数看"最小值是否恰在待排首位":在则免换;本题只有第三轮免。
排除法:选 的人把"已位免换"那轮也算了;选 的人超过上限 更不对;选 的人把比较次数混了进来。
插入排序的基本思想最像( )。
考点:抽牌插入思想(D1)。
(D1)考点:插入排序 = 摸牌整理:手牌(前缀)始终有序,每摸一张(下一个元素)在有序手牌中找位插入。
解析:生活原型最贴近的排序;"前缀有序、逐个吸收"是它的不变量(D2)。
排除法:抽最小放前是选择;相邻交换是冒泡;分半合并是归并。
插入排序进行过程中,数组前段的性质是( )。
考点:已序前缀与待插元素(D2)。
(D2)考点:插入排序的循环不变量:前缀始终有序、后段是待处理元素——每步把后段第一个插入前缀,有序区逐步长大。
解析:与前段原序无关(会移动插入)、与后段无关;不变量是理解正确性与分析复杂度的抓手。
排除法:选"前缀保持原样"的人忽略了插入会挪动前缀元素;选"完全无序"的人说反了;选"两端有序中间乱"的人那是另一种想象。
插入排序的平均与最坏时间复杂度是( )。
考点:时间复杂度(D3)。
(D3)考点:插入排序平均与最坏 :每个元素平均要挪过前缀的一半。
解析:最坏 = 完全逆序,每个新元素一路挪到最前(D10);最好 = 已序,一路不挪(D4)。
排除法:选" 与 "的人按快排记忆;选" 与 "的人把最好当成了平均;选""的人臆造。
对已经有序的 做插入排序,元素移动次数是( )。
考点:最好情况(D4)。
(D4)考点:已序 :每个新元素只与前缀末尾比一次、零移动——移动次数 ,接近 。
解析:插入的"零移动好情况"无需专门优化代码、天然成立(冒泡要加提前退出才有);这就是基本有序数据选它的底气(D11)。
排除法:选 的人把比较次数当成了移动;选 的人按最坏 算;选 的人多数了一项。
插入排序中,内层把严格大于待插元素的项依次后移,相等的那项不动(待插元素插在它后面)。这样的结果是( )。
考点:稳定性(D5)。
(D5)考点:内层仅对严格大于待插元素的后移,相等者不动、待插元素落在相等者之后——后出现的排在后面,次序保持,插入排序稳定。
解析:又是"相等时动不动"判据:插入不动相等者(后移条件 > 不是 >=),稳定。
排除法:选"被打乱"的人没看严格大于;选"取决于数据"的人稳定性是算法固有性质;选"逆序才稳定"的人无据。
阅读插入排序片段:
01int t = a[i], j = i - 1; 02while (j >= 0 && a[j] > t) { a[j + 1] = a[j]; --j; } 03a[j + 1] = t;
while 循环体的 a[j + 1] = a[j]; 做的是( )。
考点:后移腾位实现(D6)。
(D6)考点:a[j + 1] = a[j] 把比待插元素大的项逐个后移一位,为待插元素腾出位置——挪的是前缀里的"大个子"。
解析:方向从右往左逐个覆盖,腾出的空位最后由 a[j+1] = t 补上;这是插入排序的核心三行。
排除法:选"把待插元素后挪"的人挪反了对象;选"交换相邻"的人没看是赋值不是 swap;选"删除"的人无中生有。
插入排序片段 while (j >= 0 && a[j] > t) 中 j >= 0 的作用是( )。
考点:内层 while 条件(D7)。
(D7)考点:j >= 0 防左越界:待插元素比前缀所有元素都小时,扫描会走到最左端,没有该条件就读 a[-1]。
解析:短路顺序 j >= 0 在前、a[j] > t 在后——先保证下标合法再取值(与 06 卷网格判界同理)。
排除法:选"加快循环"的人它不提速只保命;选"保证稳定性"的人那是严格大于的功劳;选"可删掉"的人删了就埋越界雷。
对 做插入排序第一步(把第 个元素插入前缀)后,数组是( )。
考点:一步后的状态(D8)。
(D8)考点: 第一步插入 : 后移、 落首——得 1 3 2。
解析:一步只处理一个元素;前缀 有序、尾部 待理。
排除法:选 1 2 3 的人跑完了;选原序的人没插入;选 2 1 3 的人插错了元素。
对 做插入排序两步后,数组是( )。
考点:两步后的状态(D9)。
(D9)考点:接 1 3 2 第二步插入 : 后移、 插中间——得 1 2 3, 个元素两步完成。
解析: 个元素恰好 步;本题两步收工,无需第三步。
排除法:选 1 3 2 的人只走了一步;选 2 1 3、3 1 2 的人插入位置找错。
对完全逆序的 做插入排序,元素移动总次数是( )。
考点:逆序输入移动次数(D10)。
(D10)考点:完全逆序 :第 个元素要挪过前面全部 个——总移动 (即 )。
解析:逆序输入 = 每步都触发最深移动;移动次数与冒泡的交换次数同为 ——两种口径度量同一份"乱度"。
排除法:选 的人只算了单层;选 的人把比较也混进或按 算;选 的人只看了最后一步。
三种平方级排序中,数据基本有序时实际耗时明显更短的是( )。
考点:基本有序数据最适用(D11)。
(D11)考点:三种平方排序中,插入排序独享"基本有序就近线性"红利(每元素挪几步就位);选择不吃数据形态、冒泡要靠优化才能沾光。
解析:实战里 sort 内部对小区间也换用插入收尾——工业实现都认这个特性(I8)。
排除法:选选择的人比较次数恒定、沾不到红利;选冒泡的人不带优化时空跑到 ;选"完全一样"的人无视三者的数据敏感性差异。
计数排序的核心思路是( )。
考点:值域桶思想(E1)。
(E1)考点:计数排序开一个覆盖值域的桶数组,统计每个值出现次数,再按值序倒出——全程不比较元素大小。
解析:值即下标:cnt[v] 记值 的个数;顺序由下标天然给出,比较被"数格子"取代。
排除法:递归分区是快排、相邻交换是冒泡、取堆顶是堆排——三者都比大小。
计数排序的时间复杂度是( )( 为元素个数、 为值域大小)。
考点:复杂度 n 加值域(E2)。
(E2)考点:计数排序时间 ( 个元素各进桶一次、 个桶各倒一次)+ 空间 。
解析: 与 谁大看谁;值域小(如百分制分数)时近似线性飞快。
排除法: 是比较类挡位; 是平方家族; 无此算法。
计数排序不适合的场景是( )。
考点:值域限制(E3)。
(E3)考点:计数排序的命门是值域:桶数组要开 个——值域 的 long long 直接出局; 以内、百分制、几十种字符都是好场景。
解析:判适合与否第一问"值多大、多稠密";值大数少时比较排序才是正道。
排除法: 以内整数、 分数、几十种字符都开得起桶;唯独 值域开不出。
阅读程序:
01int a[5] = {3, 1, 3, 2, 1}; 02int cnt[4] = {0, 0, 0, 0}; 03for (int i = 0; i < 5; ++i) 04 cnt[a[i]]++;
循环结束后 cnt[3] 是( )。
考点:统计代码(E4)。
(E4)考点:cnt[a[i]]++ 一遍统计: 得 —— 出现 次,cnt[3] 是 。
解析:统计是计数排序第一阶段;桶下标与值一一对应(值 的计数在 cnt[v])。
排除法:选 的人数的是 的个数;选 的人把值当成了计数;选 的人给的是总元素数。
接统计结果:按值从小到大、每个值 cnt[v] 次地输出, 的输出序列是( )。
考点:正序扫描输出(E5)。
(E5)考点:按值从小到大、每个值输出 cnt[v] 次: → 1 1 2 3 3。
解析:这是朴素版(不保同值元素身份次序);要稳定需倒序填充版(E6)。
排除法:选原序的人没做输出阶段;选 1 2 3 的人去重了(E9 才去重);选 3 3 2 1 1 的人倒着扫桶。
要让计数排序对同值元素保持输入次序(稳定版),标准做法是( )。
考点:倒序填充稳定版(E6)。
(E6)考点:稳定版计数排序:先对 cnt 求前缀和,再从后往前扫描原数组,每个元素放进其值的当前位置、位置减一——后扫的同值元素占靠前格子,先扫的留在后面,次序保持。
解析:稳定计数是多关键字排序的地基(E8);"倒扫+位置递减"是保序的全部机关。
排除法:正序填充的人同值次序反转;先反转数组的人答非所问;"天生稳定"的人朴素版恰恰丢了身份次序。
稳定版计数排序中,cnt 求前缀和后 cnt[v] 的含义变成( )。
考点:前缀和定位(E7)。
(E7)考点:cnt 求前缀和后,cnt[v] = 值 的元素总数 = 值 在输出数组中可占用的最后一个位置。
解析:每个值分到一段连续位置:从"次数"到"末位置",前缀和完成了从计数到定位的升级。
排除法:选"出现次数"的人那是求和前;选"值的下标"的人混淆概念;选"值域大小"的人把总量当成了定位。
用(稳定)计数排序按双关键字 排序:先按 再按 都升序。正确顺序是( )。(2019 年完善程序真题的骨架)
考点:双关键字先次后主(E8)。
(E8)考点:双关键字 排序:先按次要关键字 排,再按主要关键字 排——第二轮用稳定排序, 相同者保住第一轮 的次序。(2019 年完善程序真题骨架:先第二关键字再第一关键字)
解析:顺序颠倒(先主后次)会让第二轮覆盖第一轮成果;稳定+先次后主 = 一次到位,正是稳定性存在的意义(A4)。
排除法:选"先主后次一次即可"的人次序被第二轮搅乱;选"同时比较"的人那就成了三路比较不是两趟计数;选"先 再 恰好错误"的人恰好说反——那正是正确顺序。
桶 ,若只要去重后的升序输出(每个值一次),输出是( )。
考点:去重输出(E9)。
(E9)考点:桶 去重输出 = 每个非空桶各一次:1 2 3。
解析:计数排序改输出规则即得去重升序——"桶非空"就是"值出现过";比哈希去重+排序两步更直接。
排除法:选 1 1 2 3 3 的人没去重;选 3 2 1 的人倒序扫桶;选 1 3 的人漏了非空桶 。
要对含负数(如 )的成绩计数排序,下标处理办法是( )。
考点:负数偏移(E10)。
(E10)考点:负值域用偏移平移: 统一加 映射到 ,桶照开、输出时减回去。
解析:桶下标必须非负——平移是标准解法;这与 07 卷"值当下标"的映射思想一脉相承。
排除法:选"不能排"的人没想起平移;选"负下标数组"的人 C++ 不支持;选"改成 0"的人把真实数据篡改成了 ,值全错。
归并排序的总体策略是( )。
考点:分治思想(F1)。
(F1)考点:归并排序 = 分治:分到单元素(天然有序),治=逐层把两个有序段合并成更长有序段, 层合并回整体。
解析:分而治之的两半各交给递归;"先拆到底、回溯合并"的节奏与快排"先分区再递归"相反。
排除法:基准分区是快排;选最小换前是选择;扔桶是计数。
归并排序递归函数的核心结构是( )。
考点:递归框架(F2)。
(F2)考点:归并递归三步:msort(l, mid) 排左半 → msort(mid+1, r) 排右半 → merge 合并两半。
解析:递归到单元素返回(F9),回溯时自底向上两两合并;框架顺序"先递归后合并"。
排除法:选"一步完成无递归"的人那只是一次 merge;选"先 merge 再递归"的人半段还没序就合没意义;选"只递归左半"的人另一半没人管。
把升序段 与 合并成一个升序段,结果是( )。
考点:合并两个有序段(F3)。
(F3)考点:双下标取小合并 与 : 依次出列——1 2 3 4 5 6。
解析:两段各一个指针,每轮较小的出列、指针前移;一段空了另一段整段接上。
排除法:选拼接原序的人没合并;选"右段在前"的人方向反;选 1 2 4 3 5 6 的人中途取错了段。
合并 与 (双下标取小法),关键字比较总次数是( )。
考点:合并比较次数(F4)。
(F4)考点: 与 合并比较 次:、、、、——最后剩 免比直接接上。
解析:比较次数 :每比较一次至少出列一个元素,最后剩的那个免比。
排除法:选 的人只数了一段的指针;选 的人漏了 那次;选 的人把免比的尾巴也算了。
归并排序的时间复杂度(最好、平均、最坏)是( )。
考点:时间复杂度(F5)。
(F5)考点:归并排序最好、平均、最坏全是 :拆分固定 层、每层合并共 ,与数据无关。
解析:分区平衡(永远对半)是它的定海神针——对比快排的分区随基准波动(G5);"最坏也稳"是它的招牌。
排除法:选最好 的人把它当成了插入;选最坏 的人把它当成了快排;选"无法确定"的人低估了它。
归并排序需要 辅助数组的原因是( )。
考点:辅助数组(F6)。
(F6)考点:合并要同时读两段、按序写入——原地挪动会覆盖还没读的数据,所以先把合并结果写进 临时数组,再整体拷回。
解析:这是归并唯一的空间开销;交换类排序(冒泡/选择/快排)无此需求。
排除法:选"递归必须开数组"的人递归只耗栈;选"为了稳定"的人稳定靠相等取左(F7);选"编译不通过"的人无稽之谈。
归并时两段当前元素相等,标准写法取左段(if (L[i] <= R[j]) 取 L[i])。这个 = 的意义是( )。
考点:稳定性细节相等取左(F7)。
(F7)考点:合并遇相等取左段(<=)——左段元素原位置更靠前,先出列即保持原次序;这个 = 正是归并稳定的关键。
解析:改成 < 相等时右段先出,稳定性立刻被破坏;一字之差定稳定性。
排除法:选"减少比较"的人方向反(不减少比较);选"写 < 完全相同"的人丢了稳定性;选"让它不稳定"的人说反。
对 个元素做归并排序,递归拆分的层数(从整段拆到单元素)是( )。
考点:递归层数(F8)。
(F8)考点: 对半拆到单元素:,共 层()。
解析:层数 = ;每层合并总量 ,层数乘出 (F5 的来源)。
排除法:选 的人把元素数当层数;选 的人按 记;选 的人多算了一层(拆到 为止)。
归并排序递归的终止条件(不再继续拆)是( )。
考点:终止条件(F9)。
(F9)考点:递归终止于"区间只剩一个元素"(l >= r)——单元素天然有序,开始向上合并。
解析:终止条件写错(如漏掉)会无限递归;单元素有序是归并正确性的起点。
排除法:选"长度小于 "的人还能再拆两层;选"数组有序时"的人归并不检查整体有序;选"深度到 "的人魔法数字。
对 做完整归并排序,结果是( )。
考点:排序结果模拟(F10)。
(F10)考点: 归并排序:拆 → 各自合并成 → 顶层合并 1 2 4 5。
解析:先在纸上画递归树再自底向上合并;小数组手模两遍,考场遇到就是送分。
排除法:选 5 4 2 1 的人倒序了;2 5 1 4 是中间态;4 1 2 5 的人底层合并错。
归并合并时若右段当前元素 小于左段剩余所有元素,则左段从当前位置到末尾的每个元素都与 构成逆序对(左元素原下标更小、值却更大)。对 归并排序过程中统计的逆序对总数是( )。(提高级经典应用,初赛了解思想)
考点:归并统计逆序对(F11)。
(F11)考点:合并时若右段元素 出列而左段还剩 个,这 个都大于 且原下标更靠前——恰好贡献 个逆序对。 的逆序对是 个:、。(提高级经典应用,初赛了解思想)
解析:一次归并顺带数完逆序对,——与冒泡交换次数互证(B9 同为 的那组数据)。
排除法:选 的人把 也算逆序(值序反了才行);选 的人漏 ;选 的人没找对。
归并排序与快速排序的对比,正确的是( )。
考点:与快排对比(F12)。
(F12)考点:归并:稳定、要 辅助空间、最坏稳 ;快排:平均更快、原地、但最坏退化 且不稳定。
解析:两大 算法互补:要稳定要保险用归并,要平均速度省内存用快排;std::sort 是快排底子的introsort(G8)。
排除法:选"都稳定都原地"的人两头全错;选"快排最坏 、归并最坏 "的人全反;选"平均复杂度不同"的人两者平均同为 。
快速排序每一轮做的事情是( )。
考点:基准分区思想(G1)。
(G1)考点:快排每轮:选基准,把小于它的挪左、大于它的挪右(分区),基准恰好落在最终位置;再对左右两区递归。
解析:分区的副产品是"基准落位"——每轮至少一个元素到达最终位置;递归边界+分区是快排全部。
排除法:相邻交换是冒泡;对半拆是归并;取堆顶是堆排。
以首元素 为基准,对 做一次分区(小的去左、大的去右),结果是( )。
考点:一次分区后的状态(G2)。
(G2)考点:以首元素 为基准分区 :小于 的 居左、 落位、 居右——得 2 1 3 4 5。
解析:分区只保证"左小右大、基准归位",左右各自内部仍无序(左区 2 1 3 还没排)——递归继续处理。
排除法:选全序 1 2 3 4 5 的人把递归也跑完了;选 5 3 1 2 4 的人把大的放左边了;选原序的人没分区。
接分区结果:基准 一次分区后落在数组的哪个下标( 起)( )。
考点:基准落位下标(G3)。
(G3)考点:分区结果 2 1 3 4 5 中基准 落在下标 ( 起)——左区 个元素正好都小于它。
解析:基准下标 = 小于基准的元素个数;它是本轮唯一确定最终位置的元素。
排除法:选 的人少算了左区一个;选 的人数到了右端;选 的人以为基准不动。
快速排序的平均时间复杂度是( )。
考点:平均复杂度(G4)。
(G4)考点:快排平均 ——平均意义下分区大致平衡,递归深度约 。
解析:注意只是平均:最坏 (G5);快排的速度优势来自常数小、缓存友好,实战均速常胜归并。
排除法:选 的人那是它的最坏;选 的人把它当成了计数;选 的人无此挡位。
数组已经升序且每次取首元素为基准,快排的表现是( )。
考点:最坏情况已序输入(G5)。
(G5)考点:已序数组 + 首元素基准 = 最坏:每轮基准都是当前最小、左区空,递归深度 、总比较 。
解析:最坏输入专治"固定取首"策略;防御手段是随机基准/三数取中(G8)。
排除法:选"一轮结束"的人把最好情况安错了地方;选"与平均一样"的人没意识到退化;选"编译器自动换基准"的人编译器不管算法策略。
快速排序不稳定的原因是( )。
考点:不稳定性(G6)。
(G6)考点:分区时元素与基准远距离交换,可能跨越与基准相等的元素——相等元素的相对次序被破坏,快排不稳定。
解析:与选择排序同一病因(隔空换位);稳定需求场景应选归并(F12)。
排除法:选"严格大于"的人比较符不背这个锅;选"递归深"的人复杂度与稳定性无关;选"其实稳定"的人反了。
快排代码若漏写"区间长度 就 return"的边界,后果是( )。
考点:递归边界不可缺(G7)。
(G7)考点:漏写"区间 返回":区间无法收敛、下标越界——递归永不停止或崩溃,边界是快排可终止的前提。
解析:快排排错常见三处:边界缺失、分区条件含等号死循环、递归区间写错;边界排第一。
排除法:选"只是变慢"的人后果远不止慢;选"编译错误"的人运行期问题编译期不查;选"自动跳过"的人没有这种自动。
工程上给快排加"随机选基准"或"三数取中"是为了( )。
考点:随机基准防退化(G8)。
(G8)考点:随机选基准/三数取中是为了防对手数据:让"已序数组配首基准"这类最坏构造失效,把每次分区切得极不平衡的概率压到极低。
解析:防的是退化概率不是绝对保证(理论上仍有坏运气,但期望仍是 );std::sort 的 introsort 另有"退化就换堆排"的保险。
排除法:选"变稳定"的人基准选择与稳定性无关;选"省递归"的人递归照旧;选"减少行数"的人恰恰多写几行。
快排在最坏情况(每次分区极度不平衡)下的递归深度是( )。
考点:递归深度(G9)。
(G9)考点:最坏情况(每轮分区 )递归深度 ——每层只除掉一个基准,链式递归 层。
解析: 大时可能爆栈(与 06 卷链形图 DFS 同理);平均深度 ;这也是快排空间开销的来源(G10)。
排除法:选 的人那是平均;选 的人递归不可能常数;选 的人深度不乘每层工作量。
快速排序的辅助空间说法正确的是( )。
考点:空间与栈开销(G10)。
(G10)考点:快排原地分区(不搬辅助数组),但递归消耗栈:平均 、最坏 。
解析:空间账两笔:数据空间(原地 )+ 调用栈(随深度);对比归并的 辅助数组。
排除法:选"必须开 数组"的人那是归并;选"一点不要"的人忘了栈;选 的人无此开销。
大根堆(最大堆)满足的性质是( )。
考点:大根堆定义(H1)。
(H1)考点:大根堆 = 每个结点值 自己左右孩子的完全二叉树——堆顶是全局最大;任何一条"父 子"的链都成立。
解析:只约束父子、不约束兄弟与跨子树大小(左子树某点可比右子树某点大);"每个结点"是全称约束(H6 建堆复杂度来源)。
排除法:选"左小右大"的人给兄弟排序了;选"整树递增"的人把层序当有序;选"只根最大"的人下面的小父子约束丢了。
用数组(下标从 起)存堆,结点 的左右孩子下标是( )。
考点:数组存堆下标公式(H2)。
(H2)考点: 起下标存完全二叉树:孩子 、,父 (整除)。
解析:与 04 卷"完全二叉树数组表示"同源;注意 起版本(孩子 、)差 ——竞赛堆模板多为 起,看清题干口径。
排除法:选 的人用了 起版本;选相邻下标的人把树当数组;选 的人那是兄弟不是孩子。
down(i)(向下调整)操作做的是( )。
考点:向下调整(H3)。
(H3)考点:down(i):结点与较大的孩子比,孩子大则交换、继续下沉,直到压过两个孩子或到底——一次 。
解析:跟较大的孩子换才能维持大根性质(跟小的换、另一个孩子还是更大);建堆与取顶全靠 down。
排除法:选"与堆顶换"的人方向反;选"移到末尾"的人那是取顶动作;选"随机交换"的人没有随机。
把无序数组建成堆的标准做法是( )。
考点:自底向上建堆(H4)。
(H4)考点:建堆从最后一个非叶结点(下标 )倒着到根,逐个 down——叶子天然是堆,只需修内点。
解析:自底向上保证每次 down 时子树已是堆;从根往下 down 则子树未修、修了白修。
排除法:选"逐个与堆顶比"的人不是建堆;选"从根往下"的人顺序反了;选"先排序"的人多此一举。
对 自底向上建大根堆,建完的数组是( )。
考点:建堆后的数组(H5)。
(H5)考点: 自底向上建大根堆:先 down 下标 ( 与 换)得 ,再 down 根( 与 换、再与 换)——得 5 4 1 3 2。
解析:建堆结果不唯一(合法堆有多种),但按标准算法手模就是这一种;堆顶 必然最大。
排除法:选 5 4 3 2 1 的人把它当成了排序结果;选原序的人没建堆;选 5 3 4 1 2 的人 down 的对象或顺序错了。
自底向上建堆的总时间复杂度是( )(不是 次 down 简单相乘)。
考点:建堆复杂度(H6)。
(H6)考点:自底向上建堆总代价 :约一半结点是叶子(下沉 层)、四分之一下沉至多 层……高度求和收敛,不是 次 的 。
解析:底层多而浅、顶层深而少——级数和为线性;这是堆排第一阶段的隐藏福利。
排除法:选 的人按每点满深相乘;选 、 的人量级全错。
堆排序的两个阶段是( )。
考点:堆排两阶段(H7)。
(H7)考点:堆排两阶段:①自底向上建大根堆;②取顶——堆顶(最大)与当前末位交换、堆大小减一、对堆顶 down,重复 次。
解析:每轮把当前最大"钉"到数组尾部,堆越缩越小;数组从尾向头逐渐就位(与冒泡同向、快得多)。
排除法:选"排序与输出"的人说了废话;选"递归与合并"的人那是归并;选"分区与递归"的人那是快排。
堆排序的时间复杂度(最好、平均、最坏)是( )。
考点:堆排复杂度(H8)。
(H8)考点:堆排最好、平均、最坏全为 :建堆 + 次 取顶调整。
解析:与归并同享"最坏也稳"(I3);且原地(优于归并的辅助数组)、但不稳定(H9)。
排除法:选最好 的人堆排不吃数据形态红利;选最坏 的人那是快排;选全 的人全错。
堆排序不稳定的根本原因是( )。
考点:堆排不稳定性(H9)。
(H9)考点:堆顶与末尾的远距离交换跨越大半数组,相等元素的相对次序随时可能被打乱——堆排不稳定。
解析:与选择排序同款病因(都是隔空换位);稳定名单里永远没有它(I5)。
排除法:选比较符的人不背锅;选"建堆方式不对"的人怎么建都有取顶交换;选"其实稳定"的人反了。
对 做完整堆排序,结果是( )。
考点:堆排结果模拟(H10)。
(H10)考点: 完整堆排序的最终输出当然是升序 1 1 3 4 5。
解析:验证手模:建堆后逐轮取顶换尾;两个 的相对身份在堆排中不保证(不稳定),但值序必然正确。
排除法:选 5 4 3 1 1 的人把数组排成了降序(那是建大根堆的中间形态倒读);选 1 3 1 4 5 的人中间漏换;选原序的人没排。
冒泡、选择、插入三种 排序,说法正确的是( )。
考点:三种平方算法对比(I1)。
(I1)考点:三兄弟数据敏感性:选择比较恒定(不吃有序红利);冒泡带提前退出可沾光;插入天然沾光(基本有序近 )。
解析:一张表记三列:比较、交换/移动、对有序输入的敏感度——选择题最爱在这三列里换着考。
排除法:选"三者比较都无关"的人只有选择如此;选"插入比较恒定"的人插入最吃数据;选"冒泡交换最少"的人冒泡恰恰交换最多。
平均时间复杂度为 的排序算法是( )。
考点:平均 nlogn 家族(I2)。
(I2)考点:平均 :归并、快排(平均)、堆排;冒泡/选择/插入平均都是 。
解析:四个选项里只有归并在"平均挡位"上名副其实;快排也是平均 但本题没出在选项。
排除法:冒泡/选择/插入平均全是平方档,逐项排除。
最坏情况仍保证 的算法是( )。
考点:最坏仍 nlogn 的算法(I3)。
(I3)考点:最坏也保证 的常用算法:归并、堆排;快排最坏 。
解析:对"最坏挡位"提问时快排落榜——它的 只是平均承诺;要保险(对抗性数据)选归并/堆排。
排除法:快排最坏平方;插入、冒泡最坏平方——唯一答案堆排(选项里没归并)。
下列全部为稳定排序的一组是( )。
考点:稳定算法清单(I4)。
(I4)考点:稳定四件套:冒泡、插入、归并、计数(稳定版);选择、快排、堆排不稳定。
解析:记忆口诀"稳定性看交换方式":只动邻居(冒泡/插入)稳、隔空换位(选择/快排/堆排)不稳、整段合并取左(归并)稳、倒序填桶(计数)稳。
排除法:B 组混入选择即错;C 组混入快排即错;D 组混入快排堆排即错。
常见排序中的不稳定三兄弟是( )。(2022 年真题以"哪个说法错误"考过其中一员)
考点:不稳定算法清单(I5)。
(I5)考点:不稳定三兄弟:选择、快排、堆排——共同病因都是远距离交换。(2022 年真题以"哪个说法错误"形式考过"选择稳定"这个错误说法)
解析:见到"哪个不稳定"先点这三个;冒泡/插入/归并/计数站对面。
排除法:A、D 两组混入了稳定成员;B 组的冒泡是稳定的。
任何基于比较的排序算法,最坏情况的比较次数下界是 。这说明( )。(提高级了解)
考点:比较排序下界(I6)。
(I6)考点:基于比较的排序最坏比较次数下界 ——想更快就不能靠比较;计数排序的线性靠值当下标绕开比较。(提高级了解)
解析: 个元素有 种排列,每次比较至多砍掉一半可能,至少要 次——下界的直觉来源。
排除法:选"归并低于下界"的人归并恰好贴着下界;选"快排违反下界"的人平均恰在下界上;选"堆排 "的人比较次数是 级。
个整数排序、时限 1 秒,最稳的选择是( )。
考点:按数据规模选择(I7)。
(I7)考点:、1 秒时限:平方算法约 次操作必超时——必须 :sort/归并/堆排。
解析:经验标尺:1 秒约 次基本操作; 在 上下就开始危险、 直接出局。
排除法:选冒泡/插入"也许有序"的人赌运气;选手写选择加 -O2 的人优化救不了量级差距。
很小(如 )或数据基本有序时,实战里往往用插入排序,原因是( )。
考点:按数据形态选择(I8)。
(I8)考点:小 或基本有序数据用插入排序:常数小、基本有序时近 、代码短——std::sort 对小区间也这么干。
解析:工业实现都在"小区间换插入"(introsort 的末段处理);学算法也要学这种工程混搭。
排除法:选"插入最坏也是 "的人它最坏 ;选"插入是线性"的人只有最好情况近线性;选"其他写不出来"的人无稽之谈。
sort(a, a + n, cmp) 中比较函数 cmp(x, y) 返回真表示( )。
考点:sort 与比较函数(I9)。
(I9)考点:cmp(x, y) 返回真表示" 排在 前面":x < y 升序、x > y 降序;默认无 cmp 即升序。
解析:记"真=前";结构体排序(J 组)全靠它表达任意次序规则;cmp 写反结果整体倒置。
排除法:选"相等"的人返回 bool 谈相等歧义;选"后面"的人方向反;选"交换"的人 cmp 不交换只表态。
名学生有姓名和分数,要按分数升序输出(同分按输入先后),排序的对象是( )。
考点:结构体排序场景(J1)。
(J1)考点:多条信息绑定排序:把每个学生的数据捆成结构体,排序时整条记录一起移动——姓名永远跟着自己的分数。
解析:只排分数数组会把对应关系全搅乱(分数与姓名错位);结构体+cmp 是多字段排序的标准载体。
排除法:选只排分数/姓名的人数据错位;选分别排两次的人两次排序互相不知道对方。
结构体按 x 排序,希望降序(大在前),比较函数应写( )。
考点:cmp 方向决定升降(J2)。
(J2)考点:按 x 降序:return a.x > b.x;——"大的排前面";< 是升序(J1 想要的)。
解析:cmp 是唯一的秩序开关:一个字符切换升降;写反了整套结果倒序。
排除法:选 < 的人排成了升序;选恒真的人 sort 失去依据(还可能崩溃);选按 y 的人排错了字段。
点集 ,按"x 升序、x 相同时 y 升序"排序后是( )。
考点:双关键字 cmp(J3)。
(J3)考点:x 升序、同 x 按 y 升序: → (1,9) (3,2) (3,5);cmp 写法 a.x != b.x ? a.x < b.x : a.y < b.y。
解析:同 x=3 的两点按 y 排: 在 前;双关键字 cmp 是结构体排序最常见形态。
排除法:选原序的人没排;选 (1,9) (3,5) (3,2) 的人同 内没按 ;选"还有一种可能"的人次序是确定的。
个平面点可能重复,统计"四角都是关键点且互不重合的矩形"前先要处理点集,正确做法是( )。(2021 年完善程序真题骨架)
考点:排序前先去重(J4)。
(J4)考点:统计矩形前先去重再排序(或排序后去掉相邻重复点)——重复点会让同一组四个点被重复计入。(2021 年完善程序真题骨架:排序前先 unique)
解析:"先去重后统计"是计数类问题的通用卫生步骤;排序后相邻重复合并是常用实现。
排除法:选"重复不影响"的人答案翻倍;选"只留第一个点"的人丢点;选"记两遍加权"的人方向反了。
区间覆盖问题先按左端点排序再贪心,"先排序"的作用是( )。(2020 年完善程序真题骨架)
考点:排序作预处理(J5)。
(J5)考点:区间覆盖先按左端点排序:有序后从左到右扫一遍贪心选取——排序给贪心铺路,是"排序作预处理"的经典范式。(2020 年完善程序真题骨架)
解析:无序时"下一个选谁"无从判断;排序把候选按扫描顺序排好队。大量贪心题的第一行都是 sort。
排除法:选"排序本身解决"的人排序只是前菜;选"为了美观"的人委屈了它;选"减少数据量"的人一个元素都没少。
下列说法错误的是( )。
考点:综合判断(J6)。
(J6)考点:选错误项:归并排序需要 辅助数组,不是原地排序;其余三项(计数不比较、选择每轮至多一换、插入基本有序近线性)皆真。
排除法:选 A 的人否定了计数的本质;选 C 的人否定了选择的换位规律;选 D 的人否定了插入的数据敏感性。
(计数排序)计数排序是一个广泛使用的排序方法。下面的程序使用双关键字计数排序,将 对 以内的整数,从小到大排序。
例如有三对整数 、、,那么排序之后应该是 、、。
输入第一行为 ,接下来 行,第 行有两个数 a[i] 和 b[i],分别表示第 对整数的第一关键字和第二关键字。
从小到大排序后输出。
数据范围 ,。
提示:应先对第二关键字排序,再对第一关键字排序。数组 ord[] 存储第二关键字排序的结果,数组 res[] 存储双关键字排序的结果。
试补全程序。
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 const int maxn = 10000000; 5 const int maxs = 10000; 6 7 int n; 8 unsigned a[maxn], b[maxn], res[maxn], ord[maxn]; 9 unsigned cnt[maxs + 1]; 10 11 int main() { 12 scanf("%d", &n); 13 for (int i = 0; i < n; ++i) 14 scanf("%d%d", &a[i], &b[i]); 15 memset(cnt, 0, sizeof(cnt)); 16 for (int i = 0; i < n; ++i) 17 ①; // 利用 cnt 数组统计数量 18 for (int i = 0; i < maxs; ++i) 19 cnt[i + 1] += cnt[i]; 20 for (int i = 0; i < n; ++i) 21 ②; // 记录初步排序结果 22 memset(cnt, 0, sizeof(cnt)); 23 for (int i = 0; i < n; ++i) 24 ③; // 利用 cnt 数组统计数量 25 for (int i = 0; i < maxs; ++i) 26 cnt[i + 1] += cnt[i]; 27 for (int i = n - 1; i >= 0; --i) 28 ④; // 记录最终排序结果 29 for (int i = 0; i < n; ++i) 30 printf("%d %d\n", ⑤); 31 return 0; 32 }
①处应填( )。
②处应填( )。
③处应填( )。
④处应填( )。
⑤处应填( )。
冒泡排序算法的伪代码如下:
输入:数组 ,。输出:按非递减顺序排序的 。
算法 BubbleSort:
1 FLAG ← n //标记被交换的最后元素位置 2 while FLAG > 1 do 3 k ← FLAG - 1 4 FLAG ← 1 5 for j = 1 to k do 6 if L(j) > L(j + 1) then do 7 L(j) ↔ L(j + 1) 8 FLAG ← j
对 个数用以上冒泡排序算法进行排序,最少需要比较多少次?( )
(最小区间覆盖)给出 个区间,第 个区间的左右端点是 。现在要在这些区间中选出若干个,使得区间 被所选区间的并覆盖(即每一个 都在某个所选的区间中)。保证答案存在,求所选区间个数的最小值。
输入第一行包含两个整数 和 (,)。
接下来 行,每行两个整数 、()。
提示:使用贪心法解决这个问题。先用 的时间复杂度排序,然后贪心选择这些区间。
试补全程序。
1 #include <iostream> 2 3 using namespace std; 4 5 const int MAXN = 5000; 6 int n, m; 7 struct segment { int a, b; } A[MAXN]; 8 9 void sort() // 排序 10 { 11 for (int i = 0; i < n; i++) 12 for (int j = 1; j < n; j++) 13 if (①) 14 { 15 segment t = A[j]; 16 ② 17 } 18 } 19 20 int main() 21 { 22 cin >> n >> m; 23 for (int i = 0; i < n; i++) 24 cin >> A[i].a >> A[i].b; 25 sort(); 26 int p = 1; 27 for (int i = 1; i < n; i++) 28 if (③) 29 A[p++] = A[i]; 30 n = p; 31 int ans = 0, r = 0; 32 int q = 0; 33 while (r < m) 34 { 35 while (④) 36 q++; 37 ⑤; 38 ans++; 39 } 40 cout << ans << endl; 41 return 0; 42 }
①处应填( )。
②处应填( )。
③处应填( )。
④处应填( )。
⑤处应填( )。
(矩形计数)平面上有 个关键点,求有多少个四条边都和 x 轴或者 y 轴平行的矩形,满足四个顶点都是关键点。给出的关键点可能有重复,但完全重合的矩形只计一次。
试补全枚举算法。
1 #include <iostream> 2 3 using namespace std; 4 5 struct point { 6 int x, y, id; 7 }; 8 9 bool equals(point a, point b) { 10 return a.x == b.x && a.y == b.y; 11 } 12 13 bool cmp(point a, point b) { 14 return ①; 15 } 16 17 void sort(point A[], int n) { 18 for (int i = 0; i < n; i++) 19 for (int j = 1; j < n; j++) 20 if (cmp(A[j], A[j - 1])) { 21 point t = A[j]; 22 A[j] = A[j - 1]; 23 A[j - 1] = t; 24 } 25 } 26 27 int unique(point A[], int n) { 28 int t = 0; 29 for (int i = 0; i < n; i++) 30 if (②) 31 A[t++] = A[i]; 32 return t; 33 } 34 35 bool binary_search(point A[], int n, int x, int y) { 36 point p; 37 p.x = x; 38 p.y = y; 39 p.id = n; 40 int a = 0, b = n - 1; 41 while (a < b) { 42 int mid = ③; 43 if (④) 44 a = mid + 1; 45 else 46 b = mid; 47 } 48 return equals(A[a], p); 49 } 50 51 const int MAXN = 1000; 52 point A[MAXN]; 53 54 int main() { 55 int n; 56 cin >> n; 57 for (int i = 0; i < n; i++) { 58 cin >> A[i].x >> A[i].y; 59 A[i].id = i; 60 } 61 sort(A, n); 62 n = unique(A, n); 63 int ans = 0; 64 for (int i = 0; i < n; i++) 65 for (int j = 0; j < n; j++) 66 if (⑤ && binary_search(A, n, A[i].x, A[j].y) && binary_search(A, n, A[j].x, A[i].y)) { 67 ans++; 68 } 69 cout << ans << endl; 70 return 0; 71 }
①处应填( )
②处应填( )
③处应填( )
④处应填( )
⑤处应填( )
以下排序算法的常见实现中,哪个选项的说法是错误的:( )。
某同学用冒泡排序对数组 {} 进行升序排序,请问需要进行多少次元素交换?( )