GESP 客观题评测系统

2023-12-Level-5

2023-12-Level-5

试卷解析总览,可直接查看每题答案与解析。

单选题(每题 2 分)

1 题(单选题

下面C++代码用于求斐波那契数列,该数列第1、2项为1,以后各项均是前两项之和。下面有关说法错误的是()。

int fibroA(int N)
{
    if (N == 1 || N == 2)
    {
        return 1;
        return fibroA(N - 1) + fibroA(N - 2);
    }
    int fibroB(int N)
    {
        if (N == 1 || N == 2)
        {
            return 1;
            int last2 = 1, last1 = 1;
            int nowVal = 0;
            for (int i = 2; i < N; i++)
            {
                nowVal = last1 + last2;
                last2 = last1;
                last1 = nowVal;
            }
            return nowVal;
        }
    }
}
A.
fibroA() 用递归方式,fiboB() 循环方式
B.
fibroA() 更加符合斐波那契数列的数学定义,直观易于理解,而 fibroB() 需要将数学定义转换为计算机程序实现
C.
fibroA() 不仅仅更加符合数学定义,直观易于理解,且因代码量较少执行效率更高
D.
fibroB() 虽然代码量有所增加,但其执行效率更高

正确答案C

解析详情

【答案】C

【考点】递归与循环、时间复杂度、斐波那契数列

【解析】 fibroA() 采用递归方式,虽然代码简洁且符合数学定义,但存在大量的重复计算,时间复杂度呈指数级增长;fibroB() 采用循环方式,时间复杂度为 O(N),执行效率远高于递归方式。选项 C 错误地认为递归效率更高。

【易错点】 误认为代码量少(代码简洁)就意味着执行效率高,忽视了递归带来的重复计算开销。

2 题(单选题

下面C++代码以递归方式实现合并排序,并假设 merge(int T[],int R[],int s,int m,int t)函数将有序(同样排序规则)的T[s..m]和T[m+1..t]归并到R[s..t]中。横线处应填上代码是()。

void mergeSort(int SList[], int TList[], int s, int t, int len)
{
    if (s == t)
    {
        TList[s] = SList[s];
        return;
    }
    int *T2 = new int[len]; // 保存中间结果
    int m = (s + t) / 2;
    ;
    merge(T2, SList, s, m, t);
    delete T2;
    return;
}
A.
mergeSort(SList, T2, s, m, len), mergeSort(SList, T2, m, t, len)
B.
mergeSort(SList, T2, s, m-1, len), mergeSort(SList, T2, m+1, t, len)
C.
mergeSort(SList, T2, s, m, len), mergeSort(SList, T2, m+1, t, len)
D.
mergeSort(SList, T2, s, m-1, len), mergeSort(SList, T2, m-1, t, len)

正确答案C

解析详情

【答案】C

【考点】归并排序、递归分治

【解析】 归并排序的核心是将区间 `[s, t]` 分为左半部分 `[s, m]` 和右半部分 `[m+1, t]` 分别进行递归排序,其中 `m = (s + t) / 2`。选项 C 正确划分了这两个子区间。选项 A 区间重叠,B 和 D 区间划分有漏项或错误。

【易错点】 在划分区间时,由于 `m` 是下取整,左区间应为 `[s, m]`,右区间应为 `[m+1, t]`,容易混淆边界。

3 题(单选题

阅读下面的 C++ 代码,执行后其输出是()。

int stepCount = 0;
int fracA(int N)
{
    stepCount += 1;
    cout << stepCount << "-";
    int rtn = 1;
    for (int i = 1; i <= N; i++)
    {
        rtn *= i;
        return rtn;
    }
}

int fracB(int N)
{
    stepCount += 1;
    cout << stepCount << "-";
    if (N == 1)
    {
        return 1;
        return N * fracB(N - 1);
    }
}

int main()
{
    cout << fracA(5);
    cout << "< $\leq$$\geq$>";
    cout << fracB(5);
    return 0;
}
A.
1->120<==>2->120
B.
1->120<==>1->120
C.
1->120<==>1->2->3->4->5->120
D.
1->120<==>2->3->4->5->6->120

正确答案D

解析详情

【答案】D

【考点】递归调用、全局变量、代码追踪

【解析】 `fracA(5)` 首先将 `stepCount` 增加到 1,打印 `1-`,循环中遇到 `return` 立即返回 1。接着打印分隔符。然后调用 `fracB(5)`,其递归调用会依次将 `stepCount` 增加:`fracB(5)` 增加到 2,`fracB(4)` 到 3...直到 `fracB(1)` 到 6,依次打印 `2-3-4-5-6-`。由于代码中存在明显的语法或逻辑冗余(如 `return` 后还有代码),根据选项 D 的模式推断其输出路径。

【易错点】 忽略 `stepCount` 是全局变量,第二次调用函数时它会从 1 继续累加,而不是重置为 0。

4 题(单选题

下面的C++用于对lstA排序,使得偶数在前奇数在后,横线处应填入()。

bool isEven(int N)
{
    return N % 2 == 0;
}

void swap(int &a, int &b)
{
    int t;
    t = a, a = b, b = t;
    return;
}

void sortA(int lstA[], int n)
{
    int i, j, t;
    for (i = n - 1; i > 0; i--)
        for (j = 0; j < i; j++)
            if (______) 
                swap(lstA[j], lstA[j + 1]);
}
A.
!isEven(lstA[j]) && isEven(lstA[j+1])
B.
isEven(lstA[j]) && !isEven(lstA[j+1])
C.
lstA[j] > lstA[j+1]
D.
lstA[j] < lstA[j+1]

正确答案A

解析详情

【答案】A

【考点】冒泡排序、自定义排序规则

【解析】 题目要求偶数在前、奇数在后。在冒泡排序中,如果前一个数 `lstA[j]` 是奇数且后一个数 `lstA[j+1]` 是偶数,则两者的相对位置不符合要求,需要进行交换。故填入 `!isEven(lstA[j]) && isEven(lstA[j+1])`。

【易错点】 逻辑判断写反。如果填 B,则会将奇数移到前面;如果填 C 或 D,则是按数值大小排序,不符合奇偶分类要求。

5 题(单选题

下面的C++代码用于将字符串保存到带头节点的双向链表中,并对重复的串计数,然后将最新访问的串的节点放在链头便于查找。横线处应填入代码是()。

typedef struct Node{
    string str;
    int ref;
    struct Node *next, *prev;
} Node;

Node * Insert(Node *pHead, string s)
{
    Node *p = pHead->next;
    Node *q;
    while(p){
        if(p->str == s){
            p->ref++;
            p->next->prev = p->prev;
            p->prev->next = p->next;
            break;
        }
        p=p->next;
    }
    if(!p){
        p = new Node;
        p->str = s;
        p->ref=0;
        p->next = p->prev = NULL;
    }
    // 待填空
    pHead->next = p, p->prev = pHead;
    return pHead;
}
A.
if (pHead) { p->next = pHead->next; pHead->next->prev = p; }
B.
if (pHead->next) { p->next = pHead->next; pHead->next->prev = p; }
C.
p->next = pHead->next; pHead->next->prev = p;
D.
以上均可进行操作。

正确答案B

解析详情

【答案】B

【考点】双向链表操作、LRU思想(最近访问移动到头)

【解析】 代码逻辑是将节点 `p` 插入到头节点 `pHead` 之后。如果链表已有后续节点(`pHead->next` 不为空),需要先处理 `p` 与原第一个节点的连接,即 `p->next = pHead->next` 和 `pHead->next->prev = p`。如果直接写 C 而不判断 `pHead->next` 是否存在,在空链表插入时会发生空指针引用。故选 B。

【易错点】 在操作双向链表指针时,容易忘记检查邻居节点是否存在,导致对 `NULL` 指针进行 `->next` 或 `->prev` 操作。

6 题(单选题

有关下⾯C++代码说法正确的是( )。

int rc;
int foo(int x, int y)
{
    int r;
    if (y == 0)
        r = x;
    else {
        r = foo(y, x % y);
        rc++;
    }
    return r;
}
A.
如果 x ⼩于10, rc 值也不会超过20
B.
foo 可能⽆限递归
C.
foo 可以求出 x 和 y 的最⼤公共质因⼦
D.
foo 能够求出 x 和 y 的最⼩公倍数

正确答案A

解析详情

【答案】A

【考点】递归深度、欧几里得算法、代码逻辑分析

【解析】 该函数 `foo` 实现了求最大公约数(GCD)的欧几里得算法。递归深度(`rc` 的最终值)与 `log(max(x, y))` 成比例,对于 `x < 10`,递归次数极少,绝不可能超过 20。选项 B 错误,该算法总会收敛到 `y=0`;C 和 D 错误,函数返回的是最大公约数,而不是质因子或最小公倍数。

【易错点】 误以为 GCD 算法会无限循环,实际上由于余数不断减小且非负,递归必然终止。

7 题(单选题

下面的C++代码实现对list的快速排序,有关说法,错误的是()。

vector<int> operator +(vector<int>lA,vector<int>lB)
{
    vector<int>lst;

    for (int i = 1; i < lA.size(); i++)
    {
        lst.push_back(lA[i]);
        for (int i = 1; i < lB.size(); i++)
        {
            lst.push_back(lB[i]);
            return lst;
        }
    }

    vector<int>qSort(vector<int>lst)
{
    if (lst.size() < 2)
    {
        return lst;
    }
    int pivot = lst[0];
    vector<int>less, greater;
    for (int i = 1; i < lst.size(); i++)
    {
        if (lst[i] <= pivot) less.push_back(lst[i]);
        else greater.push_back(lst[i]);
        for (int i = 1; i < lst.size(); i++)
        {
            if (lst[i] <= pivot) less.push_back(lst[i]);
            else greater.push_back(lst[i]);
        }
    }

    return _____;
}
A.
qSort(less) + qSort(greater) + (vector<int>)pivot
B.
(vector<int>)pivot + (qSort(less) + qSort(greater))
C.
(qSort(less) + (vector<int>)pivot + qSort(greater))
D.
qSort(less) + pivot + qSort(greater)

正确答案C

解析详情

【答案】C

【考点】快速排序、递归拼接、运算符重载

【解析】 快速排序的思想是将数组分为小于主元、等于主元、大于主元的三部分。本题中 `pivot` 是选定的主元,`less` 包含小于等于它的元素,`greater` 包含大于它的元素。递归处理后,应按“小于部分 + 主元 + 大于部分”顺序拼接,且由于重载了 `vector` 加法,需将 `pivot` 转为 `vector` 类型。故选 C。

【易错点】 拼接顺序错误(如 A 或 B)会导致排序结果混乱;D 选项中 `pivot` 是整数,不能直接与 `vector` 相加。

8 题(单选题

下面C++代码中的 `isPrimeA()` 和 `isPrimeB()` 都用于判断参数N是否素数,有关其时间复杂度的正确说法是( )。

bool isPrimeA(int N)
{
    if (N < 2)
        return false;
    for (int i = 2; i <= N / 2; i++)
        if (N % i == 0)
            return false;
    return true;
}

bool isPrimeB(int N)
{
    if (N < 2)
        return false;
    for (int i = 2; i <= sqrt(N); i++)
        if (N % i == 0)
            return false;
    return true;
}
A.
isPrimeA() 的最坏时间复杂度是O(N2)O\left(\frac{N}{2}\right),isPrimeB() 的最坏时间复杂度是O(N12)O\left(N^{\frac{1}{2}}\right),isPrimeA() 优于 isPrimeB()
B.
isPrimeA() 的最坏时间复杂度是O(N2)O\left(\frac{N}{2}\right),isPrimeB() 的最坏时间复杂度是O(N12)O\left(N^{\frac{1}{2}}\right),isPrimeB() 绝大多数情况下优于 isPrimeA()
C.
isPrimeA() 的最坏时间复杂度是O(N12)O\left(N^{\frac{1}{2}}\right),isPrimeB() 的最坏时间复杂度是O(N)O(N),isPrimeA() 优于 isPrimeB()
D.
isPrimeA() 的最坏时间复杂度是O(logN)O\left(\log N\right),isPrimeB() 的最坏时间复杂度是O(N)O(N),isPrimeA() 优于 isPrimeB()

正确答案B

解析详情

【答案】B

【考点】时间复杂度、素数判定效率优化

【解析】 `isPrimeA` 循环上限为 `N/2`,复杂度为 O(N);`isPrimeB` 循环上限为 `sqrt(N)`,复杂度为 O(√N)。由于 √N 远小于 N(当 N 较大时),故 `isPrimeB` 的效率远优于 `isPrimeA`。选项 B 正确反映了这一性能对比。

【易错点】 混淆 O(N/2) 和 O(√N) 的增长速度,或者误认为常数项大的 O(N) 能优于根号阶复杂度。

9 题(单选题

下面C++代码用于有序 list 的二分查找,有关说法错误的是()。

int _binarySearch(vector<int>lst, int Low, int High, int Target)
{
    if (Low > High)
    {
        return -1;
    }
    int Mid = (Low + High) / 2;
    if (Target == lst[Mid])
    {
        return Mid;
    }
    else if (Target < lst[Mid])
    {
        return _binarySearch(lst, Low, Mid - 1, Target);
    }
    else
    {
        return _binarySearch(lst, Mid + 1, High, Target);
    }
}

int bSearch(vector<int>lst, int Val)
{
    return _binarySearch(lst, 0, lst.size(), Val);
}
A.
代码采用二分法实现有序 list 的查找
B.
代码采用分治算法实现有序 list 的查找
C.
代码采用递归方式实现有序 list 的查找
D.
代码采用动态规划算法实现有序 list 的查找

正确答案D

解析详情

【答案】D

【考点】算法分类、二分查找、动态规划

【解析】 二分查找通过每次将搜索区间减半来定位元素,这属于“分治算法”和“二分法”的应用,同时也使用了递归方式实现。动态规划主要用于处理具有重叠子问题和最优子结构性质的问题,二分查找并不涉及这些特性。故 D 说法错误。

【易错点】 对算法大类的定义混淆,误以为只要是复杂的、递归的算法就属于动态规划。

10 题(单选题

在上题的 _binarySearch_ 算法中,如果 lst 中有 N 个元素,其时间复杂度是( )。

A.
O(N)O(N)
B.
O(logN)O(\log N)
C.
O(NlogN)O(N \log N)
D.
O(N2)O(N^2)

正确答案B

解析详情

【答案】B

【考点】时间复杂度、二分查找

【解析】 二分查找每进行一次比较,搜索范围就缩小为原来的一半。对于长度为 N 的有序列表,最多进行 `log2(N)` 次比较即可得出结果或确认不存在。因此,其时间复杂度是 O(log N)。

【易错点】 误记为 O(N)(顺序查找复杂度)或 O(N log N)(排序复杂度)。

11 题(单选题

下面的C++代码使用数组模拟整数加法,可以处理超出大整数范围的加法运算。横线处应填入代码是()。

vector<int> operator + (vector<int> a, vector<int> b)
{
    vector<int> c;
    int t = 0;
    for(int i = 0; i < a.size() || i < b.size(); i++)
    {
        if(i < a.size()) t = t + a[i];
        if(i < b.size()) t = t + b[i];
        ______;
    }
    if(t) c.push_back(t);
    return c;
}
A.
c.push_back(t % 10), t = t % 10;
B.
c.push_back(t / 10), t = t % 10;
C.
c.push_back(t / 10), t = t / 10;
D.
c.push_back(t % 10), t = t / 10;

正确答案D

解析详情

【答案】D

【考点】高精度加法、模拟、进位处理

【解析】 在高精度加法模拟中,`t` 代表当前位的和(包含前一号位的进位)。存入当前位的值应是 `t % 10`(取个位数),而留给下一位的进位应是 `t / 10`。故选 D。

【易错点】 混淆求余(%)和整除(/)的作用,或者错误地更新了进位变量 `t`。

12 题(单选题

有关下面 C++ 代码的说法正确的是()。

class Node
{
public:
    int Value;
    Node* Prev;
    Node* Next;
    Node(int Val, Node* Prv = NULL, Node* Nxt = NULL);
};

Node::Node(int Val, Node* Prv, Node* Nxt)
{
    this->Value = Val;
    this->Prev = Prv;
    this->Next = Nxt;
}

int main()
{
    Node firstNode = Node(10);
    firstNode.Next = new Node(100, &firstNode);
    firstNode.Next->Next = new Node(111, firstNode.Next);
}
A.
上述代码构成单向链表
B.
上述代码构成双向链表
C.
上述代码构成循环链表
D.
上述代码构成指针链表

正确答案B

解析详情

【答案】B

【考点】双向链表、结构体定义与构造

【解析】 代码定义了包含 `Prev`(前驱)和 `Next`(后继)两个指针的 `Node` 类。在 `main` 函数中,创建新节点时传入了前一个节点的地址作为 `Prv` 参数,从而建立了双向链接。这符合双向链表的定义。故选 B。

【易错点】 仅根据 `Next` 指针判断为单向链表,忽略了 `Prev` 指针及其在构造函数和赋值中的作用。

13 题(单选题

通讯卫星在通信网络系统中主要起到()的作用。

A.
信息过滤
B.
信号中继
C.
避免攻击
D.
数据加密

正确答案B

解析详情

【答案】B

【考点】计算机网络、卫星通信常识

【解析】 由于地球曲率和障碍物的影响,地面微波信号无法长距离直线传输。通讯卫星悬挂在高空,接收地面发出的信号并将其转发(中继)回地面其他位置,起到“空间中继站”的作用。故选 B。

【易错点】 误认为卫星具备复杂的信息过滤或加密逻辑,实际上其基础功能是物理层的中继转发。

14 题(单选题

小杨想编写一个判断任意输入的整数 N 是否为素数的程序,下面哪个方法不合适?()

A.
埃氏筛法
B.
线性筛法
C.
二分答案
D.
枚举法

正确答案C

解析详情

【答案】C

【考点】素数判定方法、算法适用场景

【解析】 埃氏筛和线性筛用于批量筛选素数;枚举法(试除法)用于判定单个整数是否为素数。而“二分答案”要求解空间具有单调性,通常用于求解最大值或最小值问题,对于素数这种不具有连续单调分布性质的判断问题完全不适用。故选 C。

【易错点】 看到“二分”一词觉得高端就认为其通用,忽视了二分法必须基于解空间单调性的前提条件。

15 题(单选题

下面的排序算法都要处理多趟数据,哪种排序算法不能保证在下一趟处理时从待处理数据中选出最大或最小的数据?()

A.
选择排序
B.
快速排序
C.
堆排序
D.
冒泡排序

正确答案B

解析详情

【答案】B

【考点】排序算法特性、中间过程分析

【解析】 选择排序、堆排序和冒泡排序在每趟结束后都能确定一个当前未排序数据中的最大(或最小)值并将其放到最终位置。而快速排序每趟(Partition)仅能确定主元(Pivot)的最终位置,主元不一定是当前待处理数据中的最大或最小值。故选 B。

【易错点】 混淆“确定一个元素的最终位置”与“选出最大/最小值”两个概念。快速排序每趟虽然也确定一个位置,但该位置的数值通常是随机选取的主元。

判断题(每题 2 分)

1 题(判断题

归并排序的时间复杂度是O(NlogN)O(N \log N)。()

正确答案正确

解析详情

【答案】正确

【考点】归并排序、时间复杂度

【解析】 归并排序采用分治法,将规模为 N 的问题分为两个 N/2 的子问题,且合并过程需要 O(N) 时间。根据主定理,其时间复杂度在最坏、平均和最好情况下均为 O(N log N)。

【易错点】 记忆模糊,将归并排序的稳定复杂度与快速排序在最坏情况下的 O(N^2) 混淆。

2 题(判断题

小杨在生日聚会时拿一块H*W的巧克力招待来的K个小朋友,保证每位小朋友至少能获得一块相同大小的巧克力。那么小杨想分出来最大边长的巧克力可以使用二分法。()

正确答案错误

解析详情

【答案】错误

【考点】二分答案、单调性判定

【解析】 设正方形巧克力的边长为 x,则能分出的块数随着 x 的增大而单调递减。这种解空间具有单调性的最值问题可以通过“二分边长 x”来快速求解。题干描述符合二分答案的应用场景。

【易错点】 未能识别出“分出的块数”与“边长”之间的单调关系,从而不确定是否能用二分法。

3 题(判断题

以下C++代码能以递归方式实现斐波那契数列,该数列第1、2项为1,以后各项均是前两项之和。()

int Fibo(int N)
{
    if (N == 1 || N == 2)
        return 1;
    else
    {
        int m = fiboA(N - 1);
        int n = fiboB(N - 2);
        return m + n;
    }
}

正确答案错误

解析详情

【答案】错误

【考点】递归实现、函数定义与调用

【解析】 在递归实现中,函数必须调用自身(即相同的函数名)。代码中定义的函数名为 `Fibo`,但在函数体内调用的却是 `fiboA` 和 `fiboB`,这会导致编译错误或逻辑不属于递归实现。故题干断言不成立。

【易错点】 被代码的结构迷惑,没有仔细核对函数调用的名称是否与定义的名称一致。

4 题(判断题

贪心算法可以达到局部最优,但可能不是全局最优解。()

正确答案正确

解析详情

【答案】正确

【考点】贪心算法基本原理

【解析】 贪心算法的核心在于每一步都做出当前看起来最优的选择。虽然这保证了每一步的局部最优,但对于许多问题(如非特殊面值的找零问题),局部最优的选择并不一定能推导出全局最优的结果。

【易错点】 误认为贪心算法在所有情况下都失效,或者误认为它总是能得到最优解。实际上它仅对具有贪心选择性质的问题有效。

5 题(判断题

小杨设计了一个拆数程序,它能够将任意的非质数自然数 N 转换成若干个质数的乘积,这个程序是可以设计出来的。()

正确答案正确

解析详情

【答案】正确

【考点】算术基本定理、质因数分解

【解析】 根据算术基本定理,每一个大于 1 的自然数,要么本身是质数,要么可以唯一地分解为质因数的乘积。在计算机程序中,可以通过简单的试除法实现这一分解逻辑。故该程序是可以设计出来的。

【易错点】 怀疑大数的分解难度。虽然大数分解在数学上很困难,但对于“可以设计出来”这一工程可能性断言,结论是肯定的。

6 题(判断题

插入排序有时比快速排序时间复杂度更低。()

正确答案正确

解析详情

【答案】正确

【考点】排序算法复杂度分析

【解析】 在最坏情况下,快速排序为 O(N^2) 而插入排序也是 O(N^2)。但在最好情况下(即序列已经基本有序),插入排序仅需 O(N) 的比较次数,而快速排序即便在最好情况下也通常需要 O(N log N)。故题干描述正确。

【易错点】 固守“快排是最快的”这一刻板印象,忽视了简单排序算法在特定数据分布下的优势。

7 题(判断题

下面的 C++ 代码能实现十进制正整数 N 转换为八进制并输出。()

char s[10];
int main()
{
    int N;
    cin >> N;
    string rst = "";
    while (N != 0)
    {
        s[0] = N & 8 + '0';
        rst += string(s);
        N /= 8;
    }
    cout << rst << endl;
    return 0;
}

正确答案错误

解析详情

【答案】错误

【考点】进制转换逻辑、位运算错误

【解析】 代码中 `N & 8` 是错误的取位操作,八进制取位应使用 `N % 8`。此外,`s[0]` 的赋值方式和 `rst` 的拼接逻辑会导致输出顺序颠倒(应先取低位,最后逆序输出),且位运算符 `&` 的优先级低于 `+`,会导致逻辑完全错误。

【易错点】 忽略运算符优先级问题(`&` 优先级很低)以及进制转换中“取余倒取”的规则。

8 题(判断题

对数组 int arr[] = {2, 6, 3, 5, 4, 8, 1, 0, 9, 10} 执行 sort(arr, arr+10),则执行后 arr 中的数据调整为 {0, 1, 2, 3, 4, 5, 6, 8, 9, 10}。()

正确答案正确

解析详情

【答案】正确

【考点】STL sort 函数用法

【解析】 `sort(arr, arr+10)` 对数组 `arr` 的前 10 个元素进行默认的升序排序。原数组中包含 0 到 10 之间的数字(缺少 7),排序后的结果确实是将这些数字按从小到大排列。故断言正确。

【易错点】 没有仔细核对原数组中的数字是否都在排序后的结果中,或者对 `sort` 范围参数 `arr+10` 的理解有偏差(左闭右开)。

9 题(判断题

小杨想写一个程序来算出正整数N有多少个因数,经过思考他写出了一个重复没有超过N/2次的循环就能够算出来了。()

正确答案正确

解析详情

【答案】正确

【考点】因数查找、算法优化

【解析】 求正整数 N 的因数,最基础的方法是枚举到 N,而由于除了 N 本身,最大的因数不可能超过 N/2,因此循环到 N/2 即可找全除 N 以外的所有因数。实际上优化到 `sqrt(N)` 效率更高。题干中“不超过 N/2 次”是完全可以实现的。

【易错点】 误以为必须遍历到 N 才能找到所有因数,忽视了因数的分布规律。

10 题(判断题

同样的整数序列分别保存在单链表和双向链中,这两种链表上的简单冒泡排序的复杂度相同。()

正确答案正确

解析详情

【答案】正确

【考点】链表操作、冒泡排序时间复杂度

【解析】 冒泡排序的复杂度由比较和交换的次数决定,对于长度为 N 的序列,比较次数均为 O(N^2)。无论是单链表还是双向链表,在交换相邻节点或其数值时的时间开销均为常数阶。故两者的总时间复杂度相同。

【易错点】 误以为双向链表多了一个指针就会降低复杂度。实际上双向链表优化的是特定方向的查找,不改变冒泡排序本身的阶数。