三种不同方式实现对分支结点和叶结点的不同表示
***/
区分叶结点和分支结点的一种方法是使用C++的联合结构,然而,如果叶结点子类型与分支结点子类型的长度差别太大,就会使联合结构变得代效。
第二第三种方法,使用了继承的方法,这样可以更好地区分叶结点和分支结点,基类定义一个虚继承的isLeaf函数以区分它们是属于分支结点还是叶结点,第二跟第三种方法的不同点在于,它们traverse函数实现的位置不同,而一个可以周游全部结点比较方便,另一个则可以独立分支周游。
// 三种不同方式实现对分支结点和叶结点的不同表示
/**********************************************************************
区分叶结点和分支结点的一种方法是使用C++的联合结构,然而,如果叶结点
子类型与分支结点子类型的长度差别太大,就会使联合结构变得代效。
第二第三种方法,使用了继承的方法,这样可以更好地区分叶结点和分支结
点,基类定义一个虚继承的isLeaf函数以区分它们是属于分支结点还是叶结点,
第二跟第三种方法的不同点在于,它们traverse函数实现的位置不同,而一个可
以周游全部结点比较方便,另一个则可以独立分支周游。
**********************************************************************/
///
// 1.使用联合结构实现对分支结点和叶结点的不同表示
enum Nodetype{ leaf, internal}; // Enumerate node types
class VarBinNode // Generic node class
{
public:
Nodetype mytype; // Stores the type for this node
union
{
struct // Structure for internal node
{
VarBinNode* left; // left child
VarBinNode* right; // right child
operator opx; // Internal node value
}intl;
Operand var; // Leaves just store a value
};
VarBinNode (const Operand& val) // Constructor: leaf
{my type = leaf; var = val;}
VarBinNode(const Operator& op, VarBinNode* l, VarBinNode* r)
{ // Constructor: Internal
mytype = internal;
intl.opx = op;
intl.left = l;
intl.right = r;
}
bool isLeaf() {return mytype == leaf;}
VarBinNode* leftchild() {return intl.left;}
VarBinNode* rightchild() {return intl.right;}
void traverse(VarBinNode* subroot)
{ // Preorder traversal
if (subroot == NULL) return;
if (subroot -> isLeaf())
{cout << "Leaf: " << subroot -> var << "\n";}
else
{
cout << "Internal: " << subroot -> intl.opx << "\n";
traverse(subroot -> leftchild());
traverse(subroot -> rightchild());
}
}
};
///
// 2. 使用C++的类继承和虚函数来实现对分支结点与叶结点的不同表示
// 注意,这个周游函数是在两个类外的。
class VarBinNode // Node abstract base class
{
public:
virtual bool isLeaf() = 0;
};
class LeafNode: public VarBinNode // Leaf node
{
private:
operand var; // Operand value
public:
// Constructor
LeafNode(const Operand& val) {var = val;}
// Version for LeafNode
bool isLeaf() {return true;}
// Return node value
Operand value() {return var;}
};
class IntlNode: public VarBinNode // Internal node
{
private:
VarBinNode* left; // left child
VarBinNode* right; // right child
operator opx; // Operator value
public:
// Constructor
IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r)
{
opx = op;
left = l;
right = r;
}
// Version for IntlNode
bool isLeaf() {return false;}
// left child
VarBinNode* leftchild() {return left;}
// Right child
VarBinNode* rightchild() {return right;}
// Value
Operator value() {return opx;}
};
// Preorder traversal // 注意,这个周游函数是在两个类外的。
void traverse(VarBinNode *subroot)
{
if ( NULL == subroot) return; // nothing to visit
if (subroot -> isLeaf()) // Do leaf node
{
cout << "Leaf: "
<< ((LeafNode*)subroot) -> value())
<< endl;
}
else
{
cout << "Internal: "
<< ((IntlNode *)subroot) -> value() << endl;
traverse(((IntlNode *)subroot -> leftchild());
traverse(((IntlNode *)subroot -> rightchild());
}
}
///
// 3. 使用C++的类继承和虚函数来实现对分支结点与叶结点的不同表示
// 注意,这个周游函数是在类内的。
class VarBinNode // Node abstract base class
{
public:
virtual bool isLeaf() = 0;
virtual void trav() = 0;
};
class Leafode: public VarBinNode // Leaf node
{
private:
Operand var; // Operand Value
public:
// Constructor
LeafNode(const Operand& val) {var = val;}
// Version for leafnode
bool isLeaf() {return true;}
// Return node value
Operand value() {return var;}
// traverse
void trav() {cout << "Leaf: " << value() << endl;}
};
class IntlNode: public VarBinNode // Internal node
{
private:
VarBinNode* lc; // Left child
VarBinNode* rc; // Right child
Operator opx; // Operator Value
public:
// constructor
IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r)
{opx = op; lc = l; rc = r;}
// Version for IntlNode
bool isLeaf() {return false;}
// Left child
VarBinNode* left() {return lc;}
// Right child
VarBinNode* right() {return rc;}
// Value
Operator value() {return opx;}
// traverse
void trav()
{
cout << "Internal: " << value() << endl;
if(left() != NULL) left() -> trav();
if(right() != NULL) right() -> trav();
}
};
// Preorder traversal
void traverse(VarBinNode* root)
{
if (root != NULL) root -> trav();
}
***/