面试题答案
一键面试确保内存安全的特征定义
- 引用计数:为每个节点维护一个引用计数,记录指向该节点的其他节点数量。当引用计数为0时,表明该节点不再被使用,可以安全地释放内存。
- 智能指针:使用智能指针(如C++ 中的
std::shared_ptr
或std::unique_ptr
)来管理节点的内存。智能指针会在其生命周期结束时自动释放所指向的内存,从而避免内存泄漏。 - 边界检查:在进行插入和删除操作时,检查操作是否在合法的范围内。例如,删除节点时确保该节点存在,插入节点时确保目标位置合法。
代码示例(以C++ 为例,使用std::shared_ptr
实现树结构)
#include <memory>
#include <iostream>
// 定义树节点结构
struct TreeNode {
int data;
std::shared_ptr<TreeNode> left;
std::shared_ptr<TreeNode> right;
TreeNode(int value) : data(value), left(nullptr), right(nullptr) {}
};
// 插入节点函数
void insertNode(std::shared_ptr<TreeNode>& root, int value) {
if (!root) {
root = std::make_shared<TreeNode>(value);
return;
}
if (value < root->data) {
insertNode(root->left, value);
} else {
insertNode(root->right, value);
}
}
// 删除节点函数(简化版本,未处理复杂情况如删除有两个子节点的节点)
void deleteNode(std::shared_ptr<TreeNode>& root, int value) {
if (!root) return;
if (value < root->data) {
deleteNode(root->left, value);
} else if (value > root->data) {
deleteNode(root->right, value);
} else {
// 找到要删除的节点
if (!root->left) {
root = root->right;
} else if (!root->right) {
root = root->left;
}
// 这里省略了处理有两个子节点的情况
}
}
// 辅助函数,用于打印树(中序遍历)
void inorderTraversal(const std::shared_ptr<TreeNode>& root) {
if (root) {
inorderTraversal(root->left);
std::cout << root->data << " ";
inorderTraversal(root->right);
}
}
你可以使用以下方式测试这些函数:
int main() {
std::shared_ptr<TreeNode> root = nullptr;
insertNode(root, 5);
insertNode(root, 3);
insertNode(root, 7);
insertNode(root, 2);
insertNode(root, 4);
insertNode(root, 6);
insertNode(root, 8);
std::cout << "In - order traversal before deletion: ";
inorderTraversal(root);
std::cout << std::endl;
deleteNode(root, 3);
std::cout << "In - order traversal after deletion: ";
inorderTraversal(root);
std::cout << std::endl;
return 0;
}
在这个示例中,std::shared_ptr
自动管理节点的内存,在节点不再被引用时释放内存,确保了内存安全。插入和删除操作通过边界检查来保证操作的合法性。