下列关于 C++ 中继承和多态的描述中,错误的是( )。
下列代码中, d1->work(); 和 d2->work(); 输出不同结果的主要原因是( )。
01class Device { 02public: 03 virtual void work() { 04 cout << "Device is working" << endl; 05 } 06 virtual ~Device() {} 07}; 08 09class Printer : public Device { 10public: 11 void work() override { 12 cout << "Printer is printing" << endl; 13 } 14}; 15 16class Scanner : public Device { 17public: 18 void work() override { 19 cout << "Scanner is scanning" << endl; 20 } 21}; 22 23int main() { 24 Device* d1 = new Printer(); 25 Device* d2 = new Scanner(); 26 27 d1->work(); 28 d2->work(); 29 30 delete d1; 31 delete d2; 32 return 0; 33}
下面代码在 main() 中有一行会导致编译错误,请找出来。
01class Student { 02public: 03 Student(string n, int s) : name(n), score(s) {} 04 05 string getName() { 06 return name; 07 } 08 09 void setScore(int s) { 10 score = s; 11 } 12private: 13 string name; 14 int score; 15}; 16 17int main() { 18 Student stu("Tom", 85); 19 cout << stu.getName(); // ① 20 stu.setScore(90); // ② 21 stu.score = 100; // ③ 22 cout << stu.getName(); // ④ 23 return 0; 24}
某文本编辑器把用户输入的字符依次压入栈 S 。用户依次输入 X, Y, Z, W 后,连续执行两次撤销操作。每次撤销都会弹出栈顶一个字符。此时栈从栈底到栈顶的内容是( )。
假设循环队列数组长度为 ,队空判断条件为 front == rear 。入队和出队操作如下:
01const int N = 7; 02int q[N]; 03int front = 3, rear = 3; 04 05void enqueue(int x) { 06 q[rear] = x; 07 rear = (rear + 1) % N; 08} 09 10void dequeue() { 11 front = (front + 1) % N; 12}
enqueue(10); enqueue(20); enqueue(30); dequeue(); enqueue(40); dequeue(); enqueue(50);
(front, rear) 的值是( )。
以下函数 check() 用于判断一棵二叉树是否为( )。
01bool check(TreeNode* root) { 02 if (!root) return true; 03 04 queue<TreeNode*> q; 05 q.push(root); 06 07 bool hasNull = false; 08 09 while (!q.empty()) { 10 TreeNode* cur = q.front(); 11 q.pop(); 12 13 if (cur == nullptr) { 14 hasNull = true; 15 } else { 16 if (hasNull) return false; 17 q.push(cur->left); 18 q.push(cur->right); 19 } 20 } 21 22 return true; 23}
以下代码实现了二叉树的哪种遍历方式?
01void traverse(TreeNode* root) { 02 if (root == nullptr) return; 03 04 cout << root->val << " "; 05 traverse(root->left); 06 traverse(root->right); 07}
已知一棵二叉树的先序遍历序列为: A B D E H C F G ,中序遍历序列为: D B H E A F C G ,则该二叉树的后序遍历序列是( )。
有 个字符,它们出现的次数分别为: ,现在用哈夫曼编码为这些字符编码,最小加权路径长度 WPL 的值为( )。
对 n 个不同符号进行哈夫曼编码。若生成的哈夫曼树共有 个结点,则 n 的值是( )。
在格雷码中,相邻两个编码只能有一位不同。若当前编码为 110 ,则它的下一个编码不可能是( )。
给定一棵二叉树,采用广度优先搜索 BFS 返回其右视图,其中右视图中的每个节点都是该层最右侧的节点。横线处应填写( )。
01vector<int> rightSideView(TreeNode* root) { 02 vector<int> result; 03 if (!root) return result; 04 05 queue<TreeNode*> q; 06 q.push(root); 07 08 while (!q.empty()) { 09 int sz = q.size(); 10 for (int i = 0; i < sz; ++i) { 11 TreeNode* node = q.front(); 12 q.pop(); 13 14 __________________________ 15 16 if (node->left) q.push(node->left); 17 if (node->right) q.push(node->right); 18 } 19 } 20 21 return result; 22}
下面代码实现二叉搜索树的插入操作。假设树中不存在重复值,横线处应填写( )。
01TreeNode* insertNode(TreeNode* root, int x) { 02 if (root == nullptr) { 03 return new TreeNode(x); 04 } 05 06 if (x < root->val) { 07 __________________________ 08 } else { 09 root->right = insertNode(root->right, x); 10 } 11 12 return root; 13}
给定一个整数数组 a ,每个元素表示一个位置上的数值。要求从数组中选择若干个元素,使得任意两个被选择的元素在原数组中都不相邻,并且所选元素的总和最大。函数 choose(vector<int>& a) 返回能够得到的最 大总和,则横线处应填写( )。
01int choose(vector<int>& a) { 02 if (a.empty()) return 0; 03 04 int n = a.size(); 05 if (n == 1) return a[0]; 06 07 vector<int> dp(n, 0); 08 dp[0] = a[0]; 09 dp[1] = max(a[0], a[1]); 10 11 for (int i = 2; i < n; ++i) { 12 dp[i] = __________________________; 13 } 14 15 return dp[n - 1]; 16}
下面代码实现 0/1 背包的一维动态规划。第 i 个物品重量为 wt[i] ,价值为 val[i] ,背包容量为 W 。横线处应填写( )。
01int knapsack(int W, vector<int>& wt, vector<int>& val) { 02 int n = wt.size(); 03 vector<int> dp(W + 1, 0); 04 05 for (int i = 0; i < n; ++i) { 06 for (int w = W; w >= wt[i]; --w) { 07 __________________________ 08 } 09 } 10 11 return dp[W]; 12}
C++ 中构造函数可以声明为虚函数,从而实现运行时多态。
通过指向 Base 的指针删除 Derived 对象时,一定会先调用 Derived 的析构函数,再调用 Base 的析构函数。
01#include <iostream> 02using namespace std; 03class Base { 04public: 05 ~Base() { 06 cout << "Base destructor" << endl; 07 } 08}; 09class Derived : public Base { 10public: 11 ~Derived() { 12 cout << "Derived destructor" << endl; 13 } 14}; 15int main() { 16 Base* p = new Derived(); 17 delete p; 18 return 0; 19}
在 C++ STL 中, stack 的 pop() 函数会返回栈顶元素并将其删除。
程序运行后会输出 2 。
01int main() { 02 queue<int> q; 03 q.push(1); 04 q.push(2); 05 q.push(3); 06 q.pop(); 07 cout << q.front() << endl; 08 return 0; 09}
下列函数试图将整数 x 插入到一棵二叉搜索树中。假设二叉搜索树满足如下性质:对于任意结点,左子树中所有结点的值均小于该结点的值,右子树中所有结点的值均大于或等于该结点的值。判断该函数是否能够在插入后保持二叉搜索树性质。
01struct TreeNode { 02 int val; 03 TreeNode* left; 04 TreeNode* right; 05 TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 06}; 07TreeNode* insertNode(TreeNode* root, int x) { 08 if (root == nullptr) { 09 return new TreeNode(x); 10 } 11 if (x < root->val) { 12 root->right = insertNode(root->right, x); 13 } else { 14 root->left = insertNode(root->left, x); 15 } 16 return root; 17}
哈夫曼编码一定唯一,只要字符频率相同,得到的编码也一定完全相同。
若用数组按层序存储完全二叉树,且根节点下标为 0 ,则下标为 i 的节点左孩子下标为 2 * i + 1 ,右孩子下标为 2 * i + 2 。
以下代码可以正确地按层换行输出二叉树的节点值。
01void printByLevel(TreeNode* root) { 02 if (!root) return; 03 04 queue<TreeNode*> q; 05 q.push(root); 06 07 while (!q.empty()) { 08 for (int i = 0; i < q.size(); ++i) { 09 TreeNode* cur = q.front(); 10 q.pop(); 11 cout << cur->val << " "; 12 13 if (cur->left) q.push(cur->left); 14 if (cur->right) q.push(cur->right); 15 } 16 cout << endl; 17 } 18}
使用栈非递归实现二叉树前序遍历时,若希望先访问左子树,通常应先将右孩子入栈,再将左孩子入栈。
动态规划问题通常要求具有最优子结构,并且常常存在重叠子问题。