GESP C++ 5级 2025.12
对如下定义的循环单链表,横线处填写( )。
// 循环单链表的结点
struct Node {
int data; // 数据域
Node* next; // 指针域
Node(int d) : data(d), next(nullptr) {}
};
// 创建一个只有一个结点的循环单链表
Node* createList(int value) {
Node* head = new Node(value);
head->next = head;
return head;
}
// 在循环单链表尾部插入新结点
void insertTail(Node* head, int value) {
Node* p = head;
while (p->next != head) {
p = p->next;
}
Node* node = new Node(value);
node->next = head;
p->next = node;
}
// 遍历并输出循环单链表
void printList(Node* head) {
if (head == nullptr) return;
Node* p = head;
_______________________ //在此处填入代码
cout << endl;
}
while (p != nullptr){
cout data next;
}
while (p->next != nullptr){
cout data next;
}
do {
cout data next;
} while (p != head);
for ( ; p ; p = p->next ) {
cout data << " ";
}
区块链技术是比特币的基础。在区块链中,每个区块指向前一个区块,构成链式列表,新区块只能接在链尾,不允许在中间插入或删除。下面代码实现插入区块添加函数,则横线处填写( )。
//区块(节点)
struct Block {
int index; // 区块编号(高度)
string data; // 区块里保存的数据
Block* prev; // 指向前一个区块
Block(int idx, const string& d, Block* p) : index(idx), data(d), prev(p) {}
};
// 区块链
struct Blockchain {
Block* tail;
// 初始化
void init() {
tail = new Block(0, "Genesis Block", nullptr);
}
// 插入新区块
void addBlock(const string& data) {
_______________________ //在此处填入代码
}
// 释放内存
void clear() {
Block* cur = tail;
while (cur != nullptr) {
Block* p = cur->prev;
delete cur;
cur = p;
}
tail = nullptr;
}
};
Block* newBlock = new Block(tail->index + 1, data, tail);
tail = newBlock->prev;
Block* newBlock = new Block(tail->index + 1, data, tail);
tail = newBlock;
Block* newBlock = new Block(tail->index + 1, data, tail->prev);
tail = newBlock;
Block* newBlock = new Block(tail->index + 1, data, tail->prev);
tail = newBlock->prev;
下面关于单链表和双链表的描述中,正确的是( )。
struct DNode {
int data;
DNode* prev;
DNode* next;
};
// 在双链表中删除指定节点
void deleteNode(DNode* node) {
if (node->prev) {
node->prev->next = node->next;
}
if (node->next) {
node->next->prev = node->prev;
}
delete node;
}
struct SNode {
int data;
SNode* next;
};
// 在单链表中删除指定节点
void deleteSNode(SNode* head, SNode* node) {
SNode* prev = head;
while (prev->next != node) {
prev = prev->next;
}
prev->next = node->next;
delete node;
}
双链表删除指定节点是 ,单链表是
双链表删除指定节点是 ,单链表是
双链表删除指定节点是 ,单链表是
双链表删除指定节点是 ,单链表是
假设我们有两个数 和 ,它们对模 同余,即 。以下哪个值不可能是 ?
3
4
6
9
下面代码实现了欧几里得算法。下面有关说法,错误的是( )。
int gcd1(int a, int b) {
return b == 0 ? a : gcd1(b, a % b);
}
int gcd2(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
gcd1() 实现为递归方式。
gcd2() 实现为迭代方式。
当 较大时,gcd1() 实现会多次调用自身,需要较多额外的辅助空间。
当 较大时,gcd1() 的实现比 gcd2() 执行效率更高。
唯一分解定理描述的内容是( )。
任何正整数都可以表示为两个素数的和。
任何大于 的合数都可以唯一分解为有限个质数的乘积。
两个正整数的最大公约数总是等于它们的最小公倍数除以它们的乘积。
所有素数都是奇数。
下述代码实现素数表的线性筛法,筛选出所有小于等于 的素数,则横线上应填的代码是( )。
vector linear_sieve(int n) {
vector is_prime(n +1, true);
vector primes;
is_prime[0] = is_prime[1] = 0; //0和1两个数特殊处理
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i);
}
________________________________ { // 在此处填入代码
is_prime[ i * primes[j] ] = 0;
if (i % primes[j] == 0)
break;
}
}
return primes;
}
for (int j = 0; j < primes.size() && i * primes[j] <= n; j++)
for(int j = sqrt(n); j <= n && i * primes[j] <= n; j++)
for (int j = 1; j <= sqrt(n); j++)
for(int j = 1; j < n && i * primes[j] <= n; j++)
下列关于排序的说法,正确的是( )。
快速排序是稳定排序。
归并排序通常是稳定的。
插入排序是不稳定排序。
冒泡排序不是原地排序。
下面代码实现了归并排序。下述关于归并排序的说法中,不正确的是( )。
void merge(vector& arr, vector& temp, int l, int mid, int r) {
int i = l, j = mid + 1, k = l;
while (i & arr, vector& temp, int l, int r) {
if (l >= r) return;
int mid = l + (r - l) / 2;
mergeSort(arr, temp, l, mid);
mergeSort(arr, temp, mid + 1, r);
merge(arr, temp, l, mid, r);
}
归并排序的平均复杂度是
归并排序需要 的额外空间
归并排序在最坏情况的时间复杂度是
归并排序适合大规模数据
下述 C++ 代码实现了快速排序算法,最坏情况的时间复杂度是( )。
int partition(vector& arr, int low, int high) {
int i = low, j = high;
int pivot = arr[low]; // 以首元素为基准
while (i = pivot) j--;
while (i & arr, int low, int high) {
if (low >= high) return;
int p = partition(arr, low, high);
quickSort(arr, low, p - 1);
quickSort(arr, p + 1, high);
}
