简单的二叉搜索树。分段故障

时间:2012-06-01 03:46:54

标签: c++ g++

只是一个简单的BST来按顺序打印数字。无法弄清楚我做错了什么。

#include <iostream>
using namespace std;

class bst {
 private:
  bst* root;
  bst* left;
  bst* right;
  int value;

 public:
  bst(const int& numb) : root(NULL), left(NULL), right(NULL) {
    value = numb;
  }

  void insert(const int& numb) {
    if (numb < value) {
      if (left == NULL) {
        left = new bst(numb);
        left->root = left;
      } else { 
        left->insert(numb);
      }
    } else if (numb > value) {
      if (right == NULL) {
        right = new bst(numb);
        right->root = right;
      } else {
       left->insert(numb);  
      }
    } else if (numb == value) {
      cout << "duplicated value" << endl;
    }
  }

  void inorder() {
    if (left == NULL) cout << value << endl;
    else left->inorder();
    right->inorder();
  }
};


int main() {
  bst tree(5);
  tree.insert(7);
  tree.insert(1);
  tree.insert(3);
  tree.insert(2);
  tree.insert(9);
  tree.insert(10);
  return 0;
}

4 个答案:

答案 0 :(得分:3)

第29行应为:

 right->insert(numb);

目前的内容为:

 left->insert(numb);

我强烈建议您查看gdb以解决此类问题。

答案 1 :(得分:1)

inorder()应该是:

if (left != NULL) left->inorder();
cout << value << endl;
if (right != NULL) right->inorder();

我认为其余的都是正确的。

答案 2 :(得分:1)

整个逻辑错误。

崩溃就在这里:

  if (right == NULL) { 
    right = new bst(numb); 
    right->root = right; 
  } else { 
   left->insert(numb);   
  } 

其他情况下使用权利,而不是留下。

答案 3 :(得分:1)

至少在我看来,你的基本设计是有缺陷的。虽然我意识到许多教科书(等等)将树描述为递归结构,其中每个节点都有两个子树,但我从来没有找到一种设计代码的好方法。

至少根据我的经验,在实际代码中,你(更好)将树中节点的概念与整个树的概念分开。外面的世界只能看到树; node应隐藏在树内,对外界不可见。

class bst {
    class node {
        int value;
        node *left;
        node *right;

        // ...

    };

    // ...

    node *root;   
};

然后我将insert拆分为两部分:一个公共函数,它接受一个值,然后转发到以root为起点的第二个函数。第二个实际遍历三个并插入新项目:

// public interface:
void insert(int v) {    
    insert(new node(v), root);
}

// private workhorse:
void insert(node *n, node *&pos) {
    if (pos == NULL)
        pos = n;
    else if (n->value < pos->value)
        insert(n,pos->left);
    else if (n->value > pos->value)
        insert(n,pos->right);
            else
                // duplicate value.
}

同样,inorder被分为公共和私人对,公众只提供一个界面,而私人一方完成所有实际工作:

// public interface:
void inorder() {
    inorder(root);
}

// private worker
void inorder(node *n) {
    if (n==NULL)
        return;
    inorder(n->left);
    std::cout << n->value << endl;
    inorder(n->right);
}

对于它的价值:是的,我已经测试了这段代码,它至少可以用你main中使用的输入。但它确实有缺点。例如,insertinorder递归地遍历树,因此一个大的,严重不平衡的树可能导致堆栈溢出。迭代地插入是相当容易的,但是对于实际使用,你通常只需切换到某种平衡树。