user2734825
user2734825

Reputation: 11

Strange bug in my splay tree implementation

I am attempting to write a C++ template struct for a splay tree, but when I try to test the code, I am getting very strange results.

This is my code for the template:

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();
    }
};

I am using this to test it:

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;
}

I inserted the element 2 and then printed the value of the root node twice. Somehow the two prints gave me two different values (2 and 10 in Ideone at http://ideone.com/RxZMyA). When I ran the program on my computer, it gave me 2 and 1875691072 instead. In both cases, when inserting a 3 after the 2, the root node's left child was a null pointer when it should be a node object containing 2.

Can someone please tell me why I am getting two different values when printing the same thing twice, and what I can do to make my splaytree.add() function work as intended? Thanks!

Upvotes: 1

Views: 117

Answers (1)

user58697
user58697

Reputation: 7923

After

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

root is an address of a local variable. By the time you print root->v, x0 is gone out of scope. All bets as to what the root really points to are off.

Upvotes: 1

Related Questions