树是图的一种特例,可定义为连通无环图。换言之,数既是极大无环图,又是极小连通图。一般来说我们讨论的树都是有根树,即所有的节点都有一个共同的祖先节点。假若对每个节点下的所有孩子节点都定义其长幼次序,则可称之为有序树。我们重点探讨有根有序树的实现。
二叉树是树的一种特例。若所有节点的孩子个数(度)不超过2,则称之为二叉树。虽然二叉树只是一种特例,但是它已经足以用来表示所有的树了。当我们将一棵树定义为有根有序树时,可将每个节点的长子作为其左子树,其相邻的兄弟作为右孩子,如此一来就可以表示所有的有序有根树了。
像列表一样,在实现二叉树的抽象数据类型之前,我们需要先定义其节点的类型。
#define BinNodePosi(T) BinNode<T>* //节点位置
#define stature(p) ((p) ? (p).height: -1) //节点高度
typedef enum { RB_RED, RB_BLACK } RBColor; //节点颜色
template <typename T> struct BinNode //二叉树结点模板类
{
/*--成员变量--*/
T data; //数值
BinNodeposi(T) parent; //父节点
BinNodeposi(T) lChild; //左孩子
BinNodeposi(T) rChild; //右孩子
int height; //高度
int npl; //左式堆
RBColor color; //颜色
/*--构造函数--*/
BinNode(): parent(NULL), lChild(NULL), rChild(NULL), height(0), npl(1), Color(RB_REB) {} //默认初始化
BinNode(T e, BinNodeposi(T) p = NULL, BinNodeposi(T) lc = NULL, BinNodeposi(T) rc = NULL, int h = 0, int l = 1, RBColor c = RB_REB)
: data(e), parent(p), lChild(lc), rChild(rc), height(h), npl(l), Color(c) {}
/*--重要接口--*/
int size(); //规模
BinNodeposi(T) insertAsLC(T const &e); //插入左孩子
BinNodeposi(T) insertAsRC(T const &e); //插入右孩子
BinNodeposi(T) succ(T const &e); //直接后继
template <typename VST> void tracLevel(VST&); //层次遍历
template <typename VST> void travPre(VST&); //先序遍历
template <typename VST> void tracIn(VST&); //中序遍历
template <typename VST> void tracPost(VST&); //后序遍历
/*--判断器、比较器--*/
bool operator>(BinNode const& bn) { return data > bn.data; }
bool operator<(BinNode const& bn) { return data < bn.data; }
bool operator==(BinNode const& bn) { return data == bn.data; }
bool operator>=(BinNode const& bn) { return data >= bn.data; }
bool operator>=(BinNode const& bn) { return data >= bn.data; }
};
为了简化算法描述同时增强可读性,可用宏来实现BinNode模板类。
#define IsRoot(x) (!((x).parent))
#define IsLeaf(x) (!((x).lChild && (x).rChild))
#define IsLChild(x) (!((x).parent) && ((x) == (x).parent.lChild))
#define IsRChild(x) (!((x).parent) && ((x) == (x).parent.rChild))
#define HasParent(x) ((x).parent)
#define HasLChild(x) ((x).lChild)
#define HasRChild(x) ((x).rChild)
#define HasChild(x) (HasLChild(x) || HasRChild(x))
#define HasBothChild(x) (HasLChild(x) && HasRChild(x))
#define sibling(p) (IsLChild(*(p)) ? (x).parent.rChild: (x).parent.lChild)
#define uncle(p) (sibling((p).parent))
下面简要介绍BinNode类主要接口的实现:
1.作为左孩子插入:
template <typename T>
BinNodePosi(T) BinNode::insertAsLC(T const &e)
{ return lChild = new BinNode(e, this); }
下面简要介绍BinNode类主要接口的实现:
2.作为右孩子插入:
template <typename T>
BinNodePosi(T) BinNode::insertAsRC(T const &e)
{ return rChild = new BinNode(e, this); }