学习笔记 二叉树模板类

//对二叉树状态性质的判断
//以内联函数的形式给出
template<typename T>inline int stature(T*  cur) {/*当前节点的高度*/
    //cur ? cur->height : -1;
    if (cur) return cur->height;
    else return -1;
}
template<typename T>inline bool IsRoot(T*  cur) {/*是否是根节点*/
    return !cur->parent;
}
template<typename T>inline bool IsLChild(T*  cur) {/*是否是左孩子*/
    return !IsRoot(cur) && (cur == cur->parent->left);
}
template<typename T>inline bool IsRChild(T*  cur) {/*是否是右孩子*/
    return !IsRoot(cur) && (cur == cur->parent->right);
}
/*是否是父节点*/
template<typename T>inline bool HasParent(T*  cur) { return !IsRoot(cur); }
/*是否具有左孩子*/
template<typename T>inline bool HasLChild(T*  cur) { 
    //cur->left ?  true : false;
    if (cur->left) return true;
    else return false;
}
/*是否具有右孩子*/
template<typename T>inline bool HasRChild(T*  cur) {
    if (cur->right)
        return true;
    else
        return false;
}
/*是否具有孩子*/
template<typename T>inline bool HasChild(T*  cur) { HasLChild(cur) || HasRChild(cur); }
/*是否同时具有左孩子和右孩子*/
template<typename T>inline bool HasBothChild(T*  cur) { HasLChild(cur) && HasRChild(cur); }
/*是否是叶节点*/
template<typename T>inline bool IsLeaf(T*  cur) { !HasChild(cur); }
//与BinNode具有特定关系的节点及指针
template<typename T>inline T* FromParentTo(T* cur) {/*来自父亲的引用*/
    //IsRoot(cur) ? _root : (IsLChild(cur) ?  cur->parent->left : cur->parent->right); 
    if (IsRoot(cur)) {
        return cur;
    }
    else if (IsLChild(cur)) {
        return cur->parent->left;
    }
    else {
        return cur->parent->right;
    }
}

二叉树的表示方法

一、引理:多叉树

一般地,树中各节点的孩子数目并不确定。每个节点的孩子均不超过K个有根树,称作K叉树。

多叉树有三种表示方法:

  • 父亲法
  • 孩子法
  • 父亲+孩子法

1、父亲法即底层组织为向量结构,记录每个节点的父亲。根据向量结构的优势可在O(1)时间得到当前节点的父子关系,但是孩子节点的查找需要遍历完所有节点,不得不花费O(n)时间。
2、孩子法可以令底层结构组织为向量或是列表,注重孩子节点的查找,父节点的查找花费O(n)时间
3、父亲+孩子法即综合二者优势,底层组织为边表结构,既记录父节点同时高效维护一个子序列来记录孩子节点。

如若建立某种关系使得能够由多叉树到二叉树的转换,并使得在此转换的意义下,任一多叉树都等价于一颗二叉树。

二、长子+兄弟法

有序多叉树中任一非叶节点都有唯一的“长子”,而且从该“长子”出发,可按照预先约定或指定的次序遍历所有孩子节点。因此,任意一颗有序多叉树都可转换为二叉树。

所以二叉树可以用二叉链表来描述,

struct BinNode{
    BinNode* left;
    BinNode* right;
    int val;
}

而三叉链表,加上父节点的指针,以“长子+兄弟+父亲”法描述一颗二叉树,比二叉链表更清晰。


//BinNode模板类

#ifndef __BINNODE_H__
#define __BINNODE_H__


#define BNodePosi(T) BinNode<T>*

//二叉树颜色,以便后续实现红黑树
const enum  RBCOLOR{
    RB_RED = 1,
    RB_BLACK
};


template<typename T> class BinNode{
public:
//数据成员,可以进一步封装,这里全部以公有给出,方便测试。
    BNodePosi(T) parent; BNodePosi(T) left; BNodePosi(T)  right;
    int height;
    int npl;//左式堆
    RBCOLOR color;
    T data;
    BinNode() :parent(NULL), left(NULL), right(NULL), height(0), npl(1), color(RB_RED) {}
    BinNode(T e, BNodePosi(T) p = NULL, BNodePosi(T) left = NULL, BNodePosi(T) right = NULL, int h = 0, int l = 1, RBCOLOR C = RB_RED) :
        data(e), parent(p), left(left), right(right), height(h), npl(l), color(C) {}
    BinNode(BinNode<T>& node) {
        parent = node->parent; left = node->left; right = node->right;
        height = node->height; npl = node->npl; color = node->color;
        data = node->data;
    }
    int size();
    BNodePosi(T) insertAsLC(T const&);
    BNodePosi(T) insertAsRC(T const&);
    BNodePosi(T) succ();
    BNodePosi(T) prec();
    /*
    *遍历接口是以函数对象的形式实现,也可以函数指针方式遍历。
    *template<typnename T>void BinNode<T>::travLevel(void(* visit)(T&)){}
    */
    template<typename VST>void travLevel(VST& visit);
    template<typename VST>void travPre(VST& visit);
    template<typename VST>void travIn(VST& visit);
    template<typename VST>void travPost(VST& visit);
    bool operator<(BinNode const& bi) { return this->data < bi.data; }
    bool operator==(BinNode const& bi) { return this->data == bi.data; }
    bool operator>(BinNode const& bi) { return this->data > bi.data; }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值