我正在尝试实现一些允许我将“Books”添加到“Student”类的二叉搜索树中的函数,但是我收到了一个奇怪的错误:
msvcr100d.dll!strcmp(unsigned char * str1,unsigned char * str2)第83行Asm
该程序完全是用C / C ++编写的,所以我不确定它为什么会返回汇编语言错误?我首先想到的是使用strcmp时出了问题,而Call Stack将第188行显示为最后执行的语句(在上面的错误之前),这意味着我可能会在某处弄乱我的递归。我正在调用“Student”的insertBook()函数,所以这里是我的“Student”类。有帮助吗?感谢。
class Student : public Personnel { //inherit from Personnel
public:
Book *bookTree;
Book* searchBookTree(Book *bookNode, char *title) {
if ((strcmp(title, bookNode->title)) < 0) //***LINE 188
return searchBookTree(bookNode->left, title);
else if ((strcmp(title, bookNode->title)) > 0)
return searchBookTree(bookNode->right, title);
else
return bookNode;
}
void insertBook(Book *node) {
Book *newBook, *parent;
newBook = node;
newBook->left = NULL;
newBook->right = NULL;
if (bookTree == NULL) { //if bookTree is empty
bookTree = newBook;
}
else {
parent = searchBookTree(bookTree, newBook->title);
newBook->left = parent->left;
newBook->right = parent->right;
}
}
void printBooks(Book *top) {
Book *root = top;
if (root != NULL) {
printBooks(root->left);
cout << "BOOK LIST" << endl;
cout << "Title:\t\t" << root->title << endl;
cout << "URL:\t\t" << root->url << endl;
printBooks(root->right);
}
}
void display() {
Personnel::display();
cout << "STUDENT" << endl;
cout << "Level:\t\t" << getLevel() << endl;
printBooks(bookTree); cout << endl;
}
Student(char *cName, char *cBirthday, char *cAddress, char *cPhone, char *cEmail, level gradeLevel)
: Personnel(cName, cBirthday, cAddress, cPhone, cEmail)
{
bookTree = NULL;
setLevel(gradeLevel);
}
};
答案 0 :(得分:1)
您的递归搜索缺少一个重要的终止测试!在某些时候,您在没有找到项目的情况下到达树的底部。因此,使用树节点的空指针调用搜索函数!问题不在strcmp
中,而是在其中一个参数表达式的空指针中。
您只考虑了该项目存在于树中并最终找到的情况,忽略了未找到的案例。
程序员不能以他们的聪明才智和他们的逻辑来衡量,而是要根据案例分析的完整程度来衡量。
答案 1 :(得分:1)
Book* searchBookTree(Book *bookNode, char *title) {
if ((strcmp(title, bookNode->title)) < 0) //***LINE 188
// What happens if bookNode->left == NULL ???
return searchBookTree(bookNode->left, title);
else if ((strcmp(title, bookNode->title)) > 0)
// What happens if bookNode->right== NULL ???
return searchBookTree(bookNode->right, title);
else
return bookNode;
}
您的搜索功能需要终止点。在顶部,我首先检查bookNode == NULL。
答案 2 :(得分:0)
您的insert
例程存在问题。我建议你让searchBookTree
只在没有找到任何内容时返回一个空指针。不要在insertBook
的实现中使用该例程。相反,您也可以递归地写insertBook
:
private:
// Inserts bookNode into tree, returning new tree:
Book *insertBookHelper(Book *tree, Book *bookNode) {
if (tree == NULL)
return bookNode; // bookNode becomes new tree
// no need to call strcmp twice!!!
int cmp = strcmp(title, bookNode->title);
if (cmp < 0) {
tree->left = insertBookHelper(tree->left, bookNode->title);
else if (cmp > 0)
tree->right = insertBookHelper(tree->right, bookNode->title);
else {
// Uh oh! Tree already contains that title, what to do?
// Answer: update!
// I don't know how to write this because I don't know
// how your Book class handles the memory for the strings,
// and what other members it has besides the title.
// this could be a possibility:
// bookNode->left = tree->left; // install same child pointers
// bookNode->right = tree->right; // into bookNode.
// *tree = *bookNode; // if Book has a sane copy constructor!!!
}
return tree;
}
public:
void insertBook(Book *node) {
tree = insertBookHelper(tree, node);
}
你看到递归是如何工作的吗?它与纯搜索有点不同。每个递归级别处理插入子树并返回新子树。通常,返回的树与进入的树完全相同!但是当插入空树时,返回的树不一样:进入的树是空指针,但是出现了一个非空指针。假装我们正在创建一个新树并将其作为旧树的替代品返回的这一技巧使得代码流畅。