【问题标题】:creating a tree function using helper functions使用辅助函数创建树函数
【发布时间】: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


    【解决方案1】:

    inorder function 和 insert function 有一些愚蠢的错误。 :( 跟我来:

    此函数用于遍历以打印出所有电影及其评分。实际发生的是分段错误。

    分段错误的原因是您正在检查左右部分即使它包含NULL。其中,当左侧部分确实存在时,您应该只检查左侧部分,右侧部分也相同。

    改变:

    void inorderTraverse(MovieNode* node) {
     if(node -> left)
        inorderTraverse(node -> left);
    
     cout << "Movie: " << node -> title << " " << node -> rating << endl;
    
     if(node -> right)
        inorderTraverse(node -> right);
    }
    

    这个功能是最让我困惑的一个。我见过的将新节点插入树中的大多数函数都需要一个指向节点 Node* 节点的指针,然后是将进入该节点的数据。所以每当我运行这个函数时,它只插入第一个节点(根),然后没有其他任何东西被插入到树中。

    由于要在准确的位置添加节点,所以必须先到该位置。然后只有你可以添加节点[或在正确的位置引用]。

    改变:

    MovieNode * insert(MovieNode* root, int ranking, string title, int year, float rating) 
    {
     if (root == NULL) {
       return new MovieNode(ranking, title, year, rating);
     }
     if (title < root -> title) {
      root->left = insert(root -> left, ranking, title, year, rating);
     }
     else if (title > root -> title) {
       root-> right = insert(root -> right, ranking, title, year, rating);
     }
    
     return root;
    }
    
    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) {
        root = insert(root, ranking, title, year, rating);
      }
    }
    

    现在,希望一切都好! ping 此处,如果您在任何地方遇到问题或输出错误。

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 2020-10-21
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      • 2019-02-24
      相关资源
      最近更新 更多