理论基础 —— 二叉树 —— 二叉链表

【二叉链表】

二叉树一般采用二叉链表存储,其基本思想是:令二叉树的每个结点对应一个链表结点,链表结点除了存放与二叉树结点有关的数据信息外,还要设置指示左右孩子的指针。 

template<class T>
struct Node{
    T data;//数据域,存放该结点的信息
    Node<T> *lchild;//左指针域,存放指向左孩子的指针,当左孩子不存在时为空
    Node<T> *rchild;//右指针域,存放指向右孩子的指针,当右孩子不存在时为空
};

如图,一个二叉链表的存储结构如下:

【实现类】

template<class T>
struct Node{
    T data;
    Node *lchild,*rchild;
};
template<class T>
class BiTree{
public:
    BiTree();//构造函数,建立一棵二叉树
    ~BiTree();//析构函数,释放各结点存储空间
    void countNode();//计算二叉树结点个数
    void countLeaf();//计算二叉树叶结点个数
    void countHeight();//计算二叉树高度
    void exchange();//交换左右子树
    void preOrder(){preOrder(root);}//前序遍历
    void inOrder(){inOrder(root);}//中序遍历
    void postOrder(){postOrder(root);}//后序遍历
    void levelOrder(){levelOrder(root);}//层次遍历
private:
    int numNode=0;//二叉树结点个数
    int numLeaf=0;//二叉树叶结点个数
    int heightTree=0;//二叉树的高度
    Node<T> *root;//指向根节点的头指针
    Node<T> *creat();//构造函数调用
    void release(Node<T> *bt);//析构函数调用
    void countNode(Node<T> *bt);//计算二叉树结点个数
    void countLeaf(Node<T> *bt);//计算二叉树叶结点个数
    int countHeight(Node<T> *bt);//计算二叉树的高度
    void exchange(Node<T> *bt);//交换左右子树
    void preOrder(Node<T> *bt);//前序遍历
    void inOrder(Node<T> *bt);//中序遍历
    void postOrder(Node<T> *bt);//后序遍历
    void levelOrder(Node<T> *bt);//层次遍历
};

【构造函数】

构造函数的功能是建立一棵二叉树,由于前序、中序、后序三种遍历方式都无法唯一确定二叉树的左右子树情况,因此针对这个问题,可将二叉树中每个结点的空指针引出一个虚结点,其值为一特定值,如:" # ",以标识为空。

将经过如上处理的二叉树称为原二叉树的扩展二叉树,通过扩展二叉树的一个遍历序列就能唯一确定一棵二叉树。

template<class T>
BiTree<T>::BiTree(){
    root=creat();
}

template<class T>
Node<T> *BiTree<T>::creat(){
    Node<T> *root;
    T ch;
    cin>>ch;
    if(ch=='#')
        root=NULL;
    else{
        root=new Node<T>;
        root->data=ch;
        root->lchild=creat();
        root->rchild=creat();
    }
    return root;
}

【析构函数】

template<class T>
BiTree<T>::~BiTree(){
    release(root);
}

template<class T>
void BiTree<T>::release(Node<T> *bt){
    if(bt!=NULL){
        release(bt->lchild);
        release(bt->rchild);
        delete bt;
    }
}

【计算二叉树结点个数】

template<class T>
void BiTree<T>::countNode(){
    countNode(root);
}

template<class T>
void BiTree<T>::countNode(Node<T> *bt){
    if(bt!=NULL){
        countNode(bt->lchild);
        numNode++;
        countNode(bt->lchild);
    }
}

【计算二叉树叶结点个数】

template<class T>
void BiTree<T>::countLeaf() {
    countLeaf(root);
}

template<class T>
void BiTree<T>::countLeaf(Node<T> *bt) {
    if (bt!=NULL) {
        if (bt->lchild==NULL && bt->rchild==NULL)
            leafcount=leafcount+1;
        else {
            countLeaf(bt->lchild);
            countLeaf(bt->rchild);
        }
    }
    return;
}

【计算二叉树的高度】

template<class T>
void BiTree<T>::countHeight() {
    heightTree=countHeight(root);
}

template<class T>
int BiTree<T>::countHeight(Node<T> *bt) {
    int lHeight=0,rHeight=0;
    if(bt==NULL)
        return 0;
    else{
        lHeight=countHeight(bt->lchild);
        rHeight=countHeight(bt->rchild);
        return max(lHeight,rHeight)+1;
    }
}

【交换左右子树】

template<class T>
void BiTree<T>::exchange(){
    exchange(root);
}
template<class T>
void BiTree<T>::exchange(Node<T> *bt){
    if(bt!=NULL){
        exchange(bt->lchild);
        exchange(bt->rchild);
        swap(bt->lchild,bt->rchild);
    }
}

【遍历】

1.前序遍历

template<class T>
void BiTree<T>::preOrder(Node<T> *bt){
    if(bt==NULL)
        return;
    else{
        cout<<bt->data;
        preOrder(bt->lchild);
        preOrder(bt->rchild);
    }
}

2.中序遍历

template<class T>
void BiTree<T>::inOrder(Node<T> *bt){
    if(bt==NULL)
        return;
    else{
        inOrder(bt->lchild);
        cout<<bt->data;
        inOrder(bt->rchild);
    }
}

3.后序遍历

template<class T>
void BiTree<T>::postOrder(Node<T> *bt){
    if(bt==NULL)
        return;
    else{
        postOrder(bt->lchild);
        postOrder(bt->rchild);
        cout<<bt->data;
    }
}

4.层次遍历

template<class T>
void BiTree<T>::levelOrder(Node<T> *bt){
    queue<Node<T> *> Q;
    if(bt!=NULL)
        Q.push(bt);
    while(!Q.empty()){
        bt=Q.front();
        Q.pop();
        cout<<bt->data;
        if(bt->lchild!=NULL)
            Q.push(bt->lchild);
        if(bt->rchild!=NULL)
            Q.push(bt->rchild);
    }
}

 

  • 19
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值