【发布时间】:2020-03-04 00:05:36
【问题描述】:
对于类,我们被要求创建一个二叉搜索树。小问题是我们的辅助函数不是头类的一部分,所以当我尝试使用我创建的辅助函数添加到树或遍历树时,它总是给我一个分段错误或错误输出。头类的代码只是为节点创建结构类
struct MovieNode{
int ranking;
string title;
int year;
float rating;
MovieNode* left = NULL;
MovieNode* right = NULL;
MovieNode(int rank, string t, int y, float r) {
title = t;
ranking = rank;
year = y;
rating = r;
}
};
源代码文件包含头文件中的所有类,以及我为帮助完成任务而创建的辅助函数。
#include "MovieTree.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
// MovieNode: node struct that will be stored in the MovieTree BST
MovieTree::MovieTree() {
this -> root = NULL;
}
MovieTree::~MovieTree() {
// delete every node and then set the root to NULL
}
我个人不知道析构函数是如何工作的。我的总是出现分段错误。
// helper function to printMovieInventory()
void inorderTraverse(MovieNode* node) {
inorderTraverse(node -> left);
cout << "Movie: " << node -> title << " " << node -> rating << endl;
inorderTraverse(node -> right);
}
void MovieTree::printMovieInventory() {
// using inorder traversal
if (root == NULL) {
cout << "Tree is Empty. Cannot print" << endl;
}
else if (root != NULL) {
inorderTraverse(root);
}
}
此函数用于遍历以打印出所有电影及其评分。实际发生的是分段错误。
// helper function to addMovieNode()
void insert(MovieNode* root, int ranking, string title, int year, float rating) {
if (root == NULL) {
root = new MovieNode(ranking, title, year, rating);
}
if (title < root -> title) {
insert(root -> left, ranking, title, year, rating);
}
else if (title > root -> title) {
insert(root -> right, ranking, title, year, rating);
}
}
void MovieTree::addMovieNode(int ranking, string title, int year, float rating) {
if (root == NULL) {
root = new MovieNode(ranking, title, year, rating);
}
else if (root != NULL) {
insert(root, ranking, title, year, rating);
}
}
这个功能是最让我困惑的一个。我见过的将新节点插入树中的大多数函数都需要一个指向节点Node* node 的指针,然后是将进入该节点的数据。所以每当我运行这个函数时,它只插入第一个节点(根),然后没有其他任何东西被插入到树中。
// helper function to findMovie()
MovieNode* compare(string title, MovieNode* root) {
if (root == NULL) {
return NULL;
}
else {
if (title.compare(root -> title) < 0) {
compare(title, root -> left);
}
else if (title.compare(root -> title) > 0) {
compare(title, root -> right);
}
else if (title.compare(root -> title) == 0) {
return root;
}
}
}
void MovieTree::findMovie(string title) {
if (root == NULL) {
cout << "Movie not found." << endl;
}
else {
MovieNode* foundMovie = compare(title, root);
if (foundMovie == NULL) {
cout << "Movie not found." << endl;
}
else {
cout << "Movie Info:" << endl;
cout << "==================" << endl;
cout << "Ranking:" << foundMovie -> ranking << endl;
cout << "Title :" << foundMovie -> title << endl;
cout << "Year :" << foundMovie -> year << endl;
cout << "rating :" << foundMovie -> rating << endl;
}
}
}
这个函数是比较电影的标题,然后遍历树来找到匹配的电影。如果它不在树中,则返回找不到电影。这个在评级、年份和排名中不断输出奇怪的值。即使找不到电影,它也会为它输出一些随机值。
// helper functino to queryMovies()
void preorderTraverse(MovieNode* node, int rating, int year) {
if (node -> rating >= rating && node -> year < year) {
cout << node -> title << "(" << node -> year << ") " << node -> rating << endl;
}
else {
preorderTraverse(node -> left, rating, year);
preorderTraverse(node -> right, rating, year);
}
}
void MovieTree::queryMovies(float rating, int year) {
if (root == NULL) {
cout << "Tree is Empty. Cannot query Movies" << endl;
}
else if (root != NULL) {
cout << "Movies that came out after " << year << " with rating at least " << rating << endl;
preorderTraverse(root, rating, year);
}
}
此功能类似于findMovie(),不同之处在于它比较年份和评分,然后打印出所有在该年之后上映且评分大于或等于该评分的电影。它没有特定的顺序执行此操作,因此我使用 preorder 遍历了树。它也会出现分段错误。
// helper function to averageRating()
int average(MovieNode* node, int sum) {
sum += node -> rating;
average(node -> left, sum);
average(node -> right, sum);
return sum;
}
void MovieTree::averageRating() {
if (root == NULL) {
cout << "Average rating:0.0" << endl;
}
else if (root != NULL) {
int avg = 0;
avg += average(root, avg);
cout << "Average rating:" << avg << endl;
}
}
顾名思义,此函数将所有评分相加,然后除以有多少节点以获得平均值。这个我还在做,所以我知道它充满了错误。
// helper function to printLevelNodes()
void getLevel(MovieNode* node, int level) {
if (node != NULL) {
if (level == 0) {
cout << "Movie: " << node -> title << " " << node -> rating << endl;
}
else if (level != 0) {
getLevel(node -> left, level - 1);
getLevel(node -> right, level - 1);
}
}
}
// helper function to printLevelNodes()
int maxLevel(MovieNode* node) {
if (node == NULL) {
return 0;
}
else {
int leftD = maxLevel(node -> left);
int rightD = maxLevel(node -> right);
if (leftD > rightD) {
return (leftD + 1);
}
else {
return (rightD + 1);
}
}
}
void MovieTree::printLevelNodes(int level) {
int max = maxLevel(root);
if (level <= max) {
getLevel(root, level);
}
}
有趣的是,最后一个函数是唯一有效的函数。这对我来说没有意义,因为我一个接一个地为辅助函数建模,但其中一些似乎不起作用。有没有办法从帮助函数访问树,即使它们不是头文件的一部分?如果没有,那么一些辅助函数是如何工作的,而其他的却不是?
【问题讨论】:
标签: c++ segmentation-fault binary-search-tree treenode