基类是Node
。 AvLNode
源自它。
在为AVLNode
调用this->Left()->Height()
时Balancefactor()
,
调用没有高度的Left()
级Node
左*
它最终会出现分段错误。
基类:
// A generic tree node class
template<class NodeType>
class Node {
string key;
NodeType* left;
NodeType* right;
NodeType* parent;
public:
Node() { key="-1"; left=NULL; right=NULL; parent = NULL;};
Node(NodeType* source) { //Copy Constructor
key=source->Key();left=source->Left();right=source->Right();parent=source->Parent();
};
void setKey(string aKey) { key = aKey; };
void setLeft(NodeType* aLeft) { left = aLeft; };
void setRight(NodeType* aRight) { right = aRight; };
void setParent(NodeType* aParent) { parent = aParent; };
string Key() { return key; };
NodeType* Left() { return left; };
NodeType* Right() { return right; };
NodeType* Parent() { return parent; };
void copyData(NodeType* source){key=source->key;};
};
派生类:
class AvlNode : public Node<AvlNode>
{
int height;
public:
AvlNode(){height=1;};
//~AvlNode();
int Height() { return height; };
int BalanceFactor(){
return this->AvlNode::Left()->Height() - this->AvlNode::Right()->Height();
};
int setHeight(int aHeight){height=aHeight;};
};
答案 0 :(得分:1)
创建AvlNode
时,其构造函数默认初始化其基础Node
。所以left
和right
指针都是null。
当然,以后您可以使用setLeft()
或setRight()
更改它,但不能保证您这样做。同样在树形结构中,你总是有没有左边或右边的叶子。并非所有节点都具有左节点和右节点。
因此,对于可靠的代码,您必须考虑将Left()
或Right()
设为空的可能性:
int BalanceFactor()
{
int hl=0, hr=0; // value of height if no child
if (Left())
hl = Left()->Height(); // only dereference the pointer if not null
if (Right())
hr = Right()->Height();
return hl-hr;
};
非常重要的评论与您的问题无关:
github上的评论中提供的代码库包含重要错误:
addNode()
中,您始终不会返回值:这可能会导致返回随机节点指针,从而导致内存损坏。当您递归addNode(...)
时,您实际上应该return (addNode(...))
)Tree::min()
,Tree::max()
和Tree::findNode()
中的同一错误也适用于递归调用。 Tree::Successor()
不会返回antything,即如果thisKey
为null)。我在此功能的最后添加了return thisKey;
。 只有在纠正了这些错误之后,才能运行没有segfault的代码。这里有一个bst.cpp and avl.cpp的运行摘录,我必须改变一条带有感叹号的轿跑车。