创建二进制搜索树时出现分段错误问题

时间:2013-11-24 19:52:46

标签: c++ segmentation-fault binary-search-tree

我开始提供我认为相关的所有代码。基本上已经定义了二进制搜索树,它已经工作,我们需要添加父节点功能。我已经做到了这一点,但我不断遇到分段错误。

template <class TKey>
class bst {
  private:
    struct node {
      node() { key=TKey(); link[0]=link[1]=NULL; parent=NULL; }
      operator TKey () { return key; }
      void print();

      TKey key;
      node *link[2];
      node *parent;
    };

  public:
    class iterator {
    public:
    private:
      friend class bst<TKey>;
      node *p;
    };
    node *prev_node;
    iterator begin() { }
    iterator end() { }

    bst() { Troot=NULL; }
    ~bst() { clear(Troot); }

    bool empty() { return Troot==NULL; }
    void clear() { clear(Troot); Troot=NULL; }

    void erase(TKey &key);
    void insert(TKey &key);

    void print_inorder() { print_inorder(Troot); }
    void print_bylevel();

  private:
    void clear(node *);

    node *minmax_key(node *, int);
    node *erase(node *, TKey &);
    node *insert(node *, TKey &);

    void print_inorder(node *);

    node *Troot;
};

这就是类定义。

template <class TKey>
void bst<TKey>::insert(TKey &key)
{
    Troot = insert(Troot, key);
}

template <class TKey>
class bst<TKey>::node *bst<TKey>::insert(node *T, TKey &key)
{

        cout << "insert1" << endl;
    if (T == NULL) {

      T = new node;
      T->key = key;
      if (prev_node != NULL)
          T->parent = prev_node;
      cout << T->parent->key;
    } else if (T->key == key) {
      cout << "key " << key << " already in tree" << endl;
    } else {
        prev_node = T;
        int dir = T->key < key;
        T->link[dir] = insert(T->link[dir], key);
    }

    return T;
}

这些是插入功能。我猜我正在做一些无序的事情,因为我仍然真的生锈了递归。当我运行使用树的测试程序时,它会输出inser1行,但随后会出现seg错误。所以我知道它在第一次插入时搞砸了。任何帮助?如果你需要看到剩下的代码,我可以把它放在一边,但是很多东西实际上并没有与我所做的改变有关。

1 个答案:

答案 0 :(得分:0)

我认为segfault就在这一行

cout&lt;&lt; T-&GT;父 - &GT;密钥;

如果T-&gt; parent为null,如果T是新创建的根(即如果prev_node == NULL),那么你就无法访问NULL值的'key'。

注意:请注意我只删除了您的代码,所以这只是我遇到的第一件事,可能还有其他错误。

编辑: 你是什​​么意思“我还有问题”,你有什么问题?

我可能不会如何实现BST插入,但我看不出任何跳出来说它是错误的。

我如何实现它而不是拥有一个全局变量prev_node,我可能会改变你的代码:

template <class TKey>
void bst<TKey>::insert(TKey &key)
{
    // Note that I have an initial prev_node of NULL
    Troot = insert(Troot, key, NULL);
}

// Note the extra function parameter
template <class TKey>
class bst<TKey>::node *bst<TKey>::insert(node *T, TKey &key, node *prev_node)
{

    cout << "insert1" << endl;
    if (T == NULL) {

      T = new node;
      T->key = key;
      // I have a habit of always using braces, so that it is easier to read.
      // This would have helped you with your initial problem.
      if (prev_node != NULL) {
          T->parent = prev_node;
      }
      //cout << T->parent->key;
    } else if (T->key == key) {
      cout << "key " << key << " already in tree" << endl;
    } else {
        int dir = T->key < key;
        T->link[dir] = insert(T->link[dir], key, T); // Note diff here
    }

    return T;
}

除非您在其他地方使用prev_node。

但是这不应该改变插入的工作方式,除非在你的实现中:

  1. prev_node由于某种原因最初不为null(在连续插入时就是这种情况,除非你在其他地方重置它)。
  2. 当你使用它时,某些东西正在改变prev_node(想想线程安全)