我的splay树实现中的奇怪错误

时间:2016-09-27 20:10:30

标签: c++ splay-tree

我正在尝试为splay树编写一个C ++模板结构,但是当我尝试测试代码时,我得到了非常奇怪的结果。

这是我的模板代码:

scala> import scalaz._
import scalaz._

scala> import Scalaz._
import Scalaz._

scala> val map1 = Map("a" -> 1,"b" -> 2, "c" -> 5)
map1: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 5)

scala> val map2 = Map("a" -> 3,"b" -> 4)
map2: Map[String, Int] = Map("a" -> 3, "b" -> 4)

scala> val map3 = map1 |+| map2
map3: Map[String, Int] = Map("a" -> 4, "b" -> 6, "c" -> 5)

我用它来测试它:

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

我插入了元素2,然后两次打印根节点的值。不知何故,两张照片给了我两个不同的值(Ideone在http://ideone.com/RxZMyA处为2和10)。当我在我的电脑上运行程序时,它给了我2和1875691072。在这两种情况下,当在2之后插入3时,根节点的左子节点应该是包含2的节点对象时为空指针。

有人可以告诉我为什么在两次打印相同的东西时我得到两个不同的值,以及我可以做些什么来使我的splaytree.add()函数按预期工作?谢谢!

1 个答案:

答案 0 :(得分:1)

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

root是局部变量的地址。当您打印root->v时,x0已超出范围。关于root真正指出的内容的所有赌注都已关闭。