C++二叉搜索树代码中isPerfectRec系列函数无法解析求排查
问题分析与修复方案
我帮你梳理了代码里的几个核心问题,尤其是导致isPerfectRec无法解析的关键原因,下面逐一说明并给出修复后的完整代码:
1. 指针访问的语法错误(isPerfectRec无法解析的核心原因)
你在isPerfectRec里的指针操作完全写错了:
- 判断指针是否为空应该用
root == NULL(C++11+推荐用nullptr),而不是*root == NULL——后者是解引用空指针,会直接触发崩溃,同时也是语法错误的来源 - 访问节点的左右子树应该用
root->left_son和root->right_son,而不是root->*left_son——->*是指向成员的指针的用法,这里完全不需要,属于误用语法
2. 非静态成员函数的调用问题
readListInter、hasOnlyOneChild都是类的非静态成员函数,main里直接调用会报错。我把这两个函数改成了static成员函数,这样就可以直接通过类名调用了。
3. 对象创建的错误
你的BinarySearchTree类只有默认构造函数,没有带参数的构造函数,所以readListInter里input = BinarySearchTree(x);是错误的。正确的做法是用new创建对象,再调用setInfo(x)初始化数据。
4. 其他细节修复
secondLargestUtil里输出值时,pinfo是指针类型,需要解引用:*root->pinfo- 移除了
main函数末尾多余的s - 修正了
readListInter里的循环逻辑,避免死循环 - 补充分插的递归实现(原代码缺失,导致插入逻辑不完整)
- 调整了
isPerfect的调用逻辑,确保递归正确执行
修复后的完整代码
#include <stdio.h> #include<iostream> #include<stack> template<typename T> class BinarySearchTree { public: BinarySearchTree<T> *left_son, *right_son, *parent; T *pinfo; BinarySearchTree() { left_son = right_son = NULL; parent = NULL; pinfo = NULL; } void setInfo(T info) { pinfo = new T; *pinfo = info; } void insert(T x) { if (pinfo == NULL) setInfo(x); else insert_rec(x); } private: // 补充分插的递归实现 void insert_rec(T x) { if (x < *pinfo) { if (left_son == NULL) { left_son = new BinarySearchTree<T>(); left_son->setInfo(x); left_son->parent = this; } else { left_son->insert_rec(x); } } else { if (right_son == NULL) { right_son = new BinarySearchTree<T>(); right_son->setInfo(x); right_son->parent = this; } else { right_son->insert_rec(x); } } } public: bool isPerfectRec(BinarySearchTree *root, int d, int level = 0) { // 空树是完美二叉树 if (root == NULL) return true; // 叶子节点:深度必须等于预设的叶子深度 if (root->left_son == NULL && root->right_son == NULL) return (d == level + 1); // 内部节点但只有一个子节点:不是完美二叉树 if (root->left_son == NULL || root->right_son == NULL) return false; // 递归检查左右子树 return isPerfectRec(root->left_son, d, level + 1) && isPerfectRec(root->right_son, d, level + 1); } // 包装函数 bool isPerfect(BinarySearchTree *root) { int d = findADepth(root); return isPerfectRec(root, d); } int findADepth(BinarySearchTree *node) { int d = 0; while (node != NULL) { d++; node = node->left_son; } return d; } // 寻找第二大元素的辅助函数 void secondLargestUtil(BinarySearchTree *root, int &c) { if (root == NULL || c >= 2) return; // 逆中序遍历:先访问右子树(最大元素优先) secondLargestUtil(root->right_son, c); c++; if (c == 2) { std::cout << "2nd largest element is " << *root->pinfo; printf("\n___\n"); return; } secondLargestUtil(root->left_son, c); } void secondLargest(BinarySearchTree *root) { int c = 0; secondLargestUtil(root, c); } // 改为静态成员函数,方便main调用 static bool hasOnlyOneChild(int pre[], int size) { int nextDiff, lastDiff; for (int i = 0; i < size - 1; i++) { nextDiff = pre[i] - pre[i + 1]; lastDiff = pre[i] - pre[size - 1]; if (nextDiff * lastDiff < 0) return false;; } return true; } // 改为静态成员函数 static BinarySearchTree<int>* readListInter() { BinarySearchTree<int>* root = NULL; BinarySearchTree<int>* temp; BinarySearchTree<int>* input; int x; std::cout << "enter number (<0 to stop): "; std::cin >> x; while (x >= 0) { input = new BinarySearchTree<int>(); input->setInfo(x); if (root == NULL) { root = input; } else { temp = root; while (true) { if (x < *temp->pinfo) { if (temp->left_son == NULL) { temp->left_son = input; input->parent = temp; break; } else { temp = temp->left_son; } } else { if (temp->right_son == NULL) { temp->right_son = input; input->parent = temp; break; } else { temp = temp->right_son; } } } } std::cout << "enter number (<0 to stop): "; std::cin >> x; } return root; } }; int main() { BinarySearchTree<int> *r = new BinarySearchTree<int>(); BinarySearchTree<int> *r1 = new BinarySearchTree<int>(); BinarySearchTree<int> *p = BinarySearchTree<int>::readListInter(); r->insert(6); r->insert(8); r->insert(1); r->insert(9); r->insert(10); r->insert(4); r->insert(13); r->insert(12); printf("\n___\n"); r1->insert(6); r1->insert(8); r1->insert(1); r1->insert(9); r1->insert(10); r1->insert(4); r1->insert(13); r1->insert(12); printf("\n___\n"); // 检查是否为完美二叉树 bool isPerfect = r->isPerfect(r); std::cout << "Tree r is " << (isPerfect ? "perfect" : "not perfect") << std::endl; // 测试第二大元素 r->secondLargest(r); int pre[] = {8, 3, 5, 7, 6}; int size = sizeof(pre)/sizeof(pre[0]); if (BinarySearchTree<int>::hasOnlyOneChild(pre, size) == true ) printf("Yes"); else printf("No"); return 0; }
内容的提问来源于stack exchange,提问作者bicanul123
相关产品推荐
相关产品推荐

