打印BST遍历时出错 - 分段故障

时间:2014-09-25 12:18:35

标签: c++ tree binary-search-tree tree-traversal

我正在编码打印BST预订和后序遍历。

类树定义如下

class BinSearchTree{
  char symbol;
  BinSearchTree  *lChild;
  BinSearchTree  *rChild;

 public:
 BinSearchTree(char letter) { symbol = letter;lChild = NULL; rChild = NULL;}
  BinSearchTree() { symbol = '0';}
  BinSearchTree* buildTree(BinSearchTree *tree, char letter);
  void printTreePreOrder (BinSearchTree *temp, std::ofstream &fp1);
  void printTreeInOrder (BinSearchTree *temp, std::ofstream &fp1);
};

我使用了一个简单的递归来创建BST

BinSearchTree* BinSearchTree::buildTree(BinSearchTree *tree, char letter){
  if (tree == NULL) {
    tree = new BinSearchTree (letter); 
    return tree;
  }
  else {
        if (letter<(tree->symbol))
        {
                tree->lChild = (BinSearchTree*) buildTree(tree->lChild, letter);
                return tree;
        }
        else{
                tree->rChild = (BinSearchTree*) buildTree(tree->rChild, letter);
                return tree;
        }
      }
    return tree;
}

但是当我打印出遍历时,我会遇到分段错误。我使用这段代码进行预购,类似于后期订单

void BinSearchTree::printTreePreOrder (BinSearchTree *temp, std::ofstream &fp1) {
    if (temp == NULL){
        return;
    }
    else{
        fp1 << symbol << " ";
        printTreePreOrder(lChild, fp1);
        printTreePreOrder(rChild, fp1);
    }
}

在我的主代码中,我使用

创建了我的树
T = new BinSearchTree(str[0]);
    for(i=1; i<num; i++){
        fp >> str[i];
        T->buildTree(T,str[i]);
    }

并使用

进行遍历
T->printTreePreOrder(T,fp1)

我一直试图找出错误,因为我认为这是一个愚蠢的错误。任何帮助表示赞赏。

PS - 使用Ubuntu 14.04并使用G ++编译器。

1 个答案:

答案 0 :(得分:0)

首先,您需要确定遍历算法在课堂上或课堂外的位置。现在该方法属于该类,但接收类的类型的参数(这看起来很奇怪,在这种特殊情况下是错误的)。

void BinSearchTree::printTreePreOrder (BinSearchTree *temp, std::ofstream &fp1);

正确的签名应该是:

void BinSearchTree::printTreePreOrder(std::ofstream &fp1)在这种情况下,您使用实际节点作为root进行迭代,代码将类似于:

void BinSearchTree::printTreePreOrder(std::ofstream &fp1) {
    fp1 << symbol << " ";
    if (lChild != NULL)
        printTreePreOrder(lChild, fp1);
    if (rChild != NULL)
        printTreePreOrder(rChild, fp1);
}

或者如果该功能不在课堂上:

void printTreePreOrder(BinSearchTree *temp, std::ofstream &fp1) {
    if (temp == NULL)
        return ;
    else {
        fp1 << temp->symbol << " ";
        if (temp->lChild != NULL)
            printTreePreOrder(temp->lChild, fp1);
        if (temp->rChild != NULL)
            printTreePreOrder(temp->rChild, fp1);
    }
}

在这种情况下,您需要访问成员symbollChildrChild在实际实现中是私有的(或将方法声明为朋友)。

您的问题是您错过了匹配参数和成员变量,例如:

在致电printTreePreOrder方法时:T->printTreePreOrder(T,fp1)在这种情况下,temp将是TlChildrChild将是T的孩子,这里没有问题,让我们假设这两个孩子存在,您打symbol T printTreePreOrder(lChild, fp1);并在此致电中致电temp lChild等于lChild,但rChildT已经引用了in class的成员变量,这就是问题所在。

在你的情况下,最好不要members variables publicfriendbuildTree

返回方法printThreePreOrder似乎很奇怪(它与void BinSearchTree::buildTree(char letter){ if (letter < tree->symbol) { if (lChild == NULL) lChild = new BinSearchTree(letter); else lChild->buildTree(letter); } else { if (rChild == NULL) rChild = new BinSearchTree(letter); else rChild->buildTree(letter); } } 有同样的问题。你不需要返回任何东西,新数据插入到实际节点中或转发给其中一个孩子,不需要退货:

代码类似于(在类版本中):

{{1}}