2016-09-27 45 views
1

我正在嘗試爲splay樹編寫一個C++模板結構,但是當我嘗試測試代碼時,我得到了非常奇怪的結果。在我的splay樹實現中的奇怪的錯誤

這是我爲模板代碼:

template <class T> 
struct splaytree { 
    struct node { 
     splaytree<T> *tree; 
     node *p, *c[2]; 
     T v; 
     int w; 
     node(T t, splaytree<T> *st) { 
      v = t; 
      p = 0; 
      c[0] = 0; 
      c[1] = 0; 
      w = 1; 
      tree = st; 
     } 
     int side() { 
      return (p->c[1] == this) ? 1:0; 
     } 
     void r() { 
      node *x = this; 
      int b = x->side(); 
      node *p = x->p; 
      x->w = p->w; 
      p->w = x->c[1^b]->w + 1 + p->c[1^b]->w; 
      x->p = p->p; 
      p->p = x; 
      p->c[0^b] = x->c[1^b]; 
      x->c[1^b] = p; 
     } 
     void splay() { 
      node *x = this; 
      while (x->p) { 
       node *p = x->p; 
       if (p == tree->root) x->r(); 
       else if (((x->side())^(p->side()))) { 
        x->r(); 
        x->r(); 
       } 
       else { 
        p->r(); 
        x->r(); 
       } 
      } 
      tree->root = this; 
     } 
     int index() { 
      this->splay(); 
      return this->c[0]->w; 
     } 
    }; 
    node *root; 
    splaytree() { 
     root = 0; 
    } 
    void add(T k) { 
     node x0(k,this); 
     node *x = &x0; 
     if (root == 0) { 
      root = x; 
      return; 
     } 
     node *i = root; 
     while (i != x) { 
      int b = (k < i->v) ? 0:1; 
      if (i->c[b] == 0) { 
       i->c[b] = x; 
       i->w++; 
       x->p = i; 
      } 
      i = i->c[b]; 
     } 
     x->splay(); 
    } 
}; 

我使用此來測試它:

int main() { 
    splaytree<int> st; 
    st.add(2); 
    cout << st.root->v << endl; 
    cout << st.root->v << endl; 
    st.add(3); 
    cout << st.root->c[0] << endl; 
} 

我插入元件2,然後打印的根節點的值的兩倍。不知何故,兩張照片給了我兩個不同的值(Ideone的2和10在http://ideone.com/RxZMyA)。當我在計算機上運行該程序時,它給了我2和1875691072。在這兩種情況下,在2之後插入3時,根節點的左側子節點應該是包含2的節點對象時爲空指針。

有人可以告訴我爲什麼在打印時獲得兩個不同的值同樣的事情兩次,以及我能做些什麼來使我的splaytree.add()函數按預期工作?謝謝!

回答

1

node x0(k,this); 
    node *x = &x0; 
    if (root == 0) { 
     root = x; 
     return; 
    } 

root是一個局部變量的地址。當您打印root->v時,x0已超出範圍。所有的投注都是關於root真正指向的。