以为我会用安德森树来做某事。所以我开始移植到C ++这里找到的Julienne Walker版本:http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_andersson.aspx
现在我有插入功能。但问题是,如果我使用优化进行编译,它会崩溃。甚至-O1也会崩溃。
template <class Tv>
class AaTree
{
private:
template <typename Tdata>
struct AaNode
{
AaNode()
{
level = 0;
link[0] = 0L;
link[1] = 0L;
}
~AaNode()
{}
int level;
Tdata data;
AaNode<Tdata>* link[2];
};
AaNode<Tv>* root;
AaNode<Tv>* nil; // sentinel
inline AaNode<Tv>* make_node(Tv data, int level)
{
AaNode<Tv>* rn = new AaNode<Tv>();
rn->data = data;
rn->level = level;
rn->link[0] = rn->link[1] = nil;
}
inline AaNode<Tv>* skew(AaNode<Tv>* t)
{
if (t->link[0]->level == t->level && t->level != 0)
{
AaNode<Tv>* save = t->link[0];
t->link[0] = save->link[1];
save->link[1] = t;
t = save;
}
return t;
}
inline AaNode<Tv>* split(AaNode<Tv>* t)
{
if (t->link[1]->link[1]->level == t->level && t->level != 0)
{
AaNode<Tv>*save = t->link[1];
t->link[1] = save->link[0];
save->link[0] = t;
t = save;
++t->level;
}
return t;
}
AaNode<Tv>* _insert(AaNode<Tv>* root, Tv data)
{
if (root == nil)
root = make_node(data, 1);
else {
AaNode<Tv>* it = root;
AaNode<Tv>* path[64];
int top=0, dir=0;
for (;;)
{
path[top++] = it;
dir = it->data < data;
if (it->link[dir] == nil)
break;
it = it->link[dir];
}
it->link[dir] = make_node(data, 1);
while (--top >= 0)
{
if (top != 0)
dir = path[top - 1]->link[1] == path[top];
path[top] = skew(path[top]);
path[top] = split(path[top]);
if ( top != 0 )
path[top - 1]->link[dir] = path[top];
else
root = path[top];
}
}
return root;
}
void _print(AaNode<Tv>* root)
{
if (root != nil)
{
_print(root->link[0]);
printf("level(%d): %d\n", root->level, root->data);
_print(root->link[1]);
}
}
public:
AaTree()
: root(0L)
{
nil = new AaNode<Tv>();
root = nil;
}
~AaTree()
{}
void Insert(Tv data)
{
root = _insert(root, data);
}
void Delete(Tv data)
{
root = _remove(root, data);
}
void Print()
{
_print(root);
}
};
int main(int argc, char* argv[])
{
AaTree<int> tree;
for (int i = 0; i < 100; i++)
tree.Insert(i);
tree.Print();
return 0;
}
答案 0 :(得分:1)
你的make_node函数声称返回一个值,但不包含return语句。
答案 1 :(得分:0)
struct AaNode
不应该是模板。尝试删除它,看看会发生什么。
struct AaNode
{
AaNode()
{
level = 0;
link[0] = 0L;
link[1] = 0L;
}
~AaNode()
{}
int level;
Tv data;
AaNode* link[2];
};
但无论如何,make_node()必须返回一个值。我不知道你怎么能编译它。
答案 2 :(得分:0)
使用正确的构造初始化列表:
AaNode()
:
level(0),
data(),
link()
{
link[0] = 0L;
link[1] = 0L;
}
从函数中删除内联关键字。内联应保留用于非常小的函数(一般准则是最多一行或两行),您尝试内联的函数太大,并且很可能比正常调用效率低。
您的传票值nil
可能应为const static
。使用一些易于识别的值来初始化它也没有什么害处,这可能有助于调试。
在skew()和split()中,在取消引用指针之前,您没有进行任何检查以确保t
有效或t的链接有效。
正如其他人所说,你的make_node不会返回它创建的节点。
在insert
你的for循环没有检查以确保它不能访问越界内存(&gt;路径的第64个条目)