二叉树节点为何用指针而非直接存节点?创建函数为何返回指针?
关于二叉树节点代码的两个疑问解答
先贴出你提到的代码:
struct Node { int data; Node* Left; Node* Right; }; Node* CreateNode(int data) { Node* newNode = new Node(); newNode->data = data; newNode->Left = newNode->Right = nullptr; return newNode; }
一、为什么结构体Node内部用Node*而不是直接用Node对象?
- 根本原因:避免无限递归定义
如果把Left和Right定义成Node对象,每个Node结构体里会包含另外两个完整的Node对象,而这两个Node又各自包含两个Node……这样结构体的内存大小会无限嵌套,编译器根本无法计算它的占用空间,直接编译报错。 - 内存效率与结构灵活性
指针仅占4或8字节(取决于系统位数),而一个完整Node对象的内存占用远大于此。用指针既能通过nullptr明确表示“无此子节点”,又能在需要时动态指向新创建的节点,灵活构建树的分支;要是用对象,既没法表示空节点,还会平白浪费大量内存。 - 避免不必要的拷贝开销
用对象的话,赋值或传递节点时会触发整个对象的拷贝,性能损耗大;而传递指针只是传一个地址,开销可以忽略。
二、为什么CreateNode函数返回Node*指针类型?
- 对应堆内存的分配逻辑
代码用new Node()在堆上创建节点,堆上的对象不会自动释放,必须通过指针持有它的地址。如果返回Node对象,就会返回堆上对象的拷贝,原堆节点会变成无主对象,直接造成内存泄漏。 - 适配树的结构设计
二叉树的节点之间靠指针关联,返回指针可以直接把新节点挂到父节点的Left或Right上,比如parent->Left = CreateNode(5),一步完成创建与挂载;要是返回对象,还要额外处理指针转换,完全多此一举。 - 支持错误状态判断
若内存不足导致new分配失败,会返回nullptr,函数返回指针的话,调用者可以通过检查返回值是否为nullptr判断节点创建是否成功;要是返回对象,根本没法表示这种失败情况。
内容的提问来源于stack exchange,提问作者Lord Touch Me
相关产品推荐
相关产品推荐

