二叉树类模版及各种函数操作

有需要的小伙伴可以借鉴代码思路,但是不要copy~

main函数

随便调试的函数,大家根据需要自己调试函数哈~

#include "BiTree.cpp"
#include <iostream>
using namespace std;
#define NodesLength 27

int main(int argc, const char * argv[]) {
    
//    char preOrder[NodesLength] = {'A', 'B', 'D', 'C', 'E', 'F'};
//    char inOrder[NodesLength] = { 'D', 'B', 'A', 'E', 'C', 'F'};
//    BiTree<char> T(preOrder, inOrder, NodesLength);
//    T.PostOrder();
    BiTree<char> T;
    cout << T.GetNodesNumberOfKthLevle(3) << endl; 
    cout << T.GetLeafNodesNumberOfKthLevel(3);
    T.PrintNodesOfKthLevel(3);
    cout << endl;
    T.PrintLeafNodesOfKthLevel(3);
    
    
    return 0;
}

.h 文件

#ifndef BiTree_hpp
#define BiTree_hpp

#include <stdio.h>
#include <stdlib.h>
template <class ElemType>
struct BiNode{
    ElemType data;
    BiNode <ElemType> *lchild,*rchild;
};

template<class ElemType>
class BiTree{
private:
    BiNode<ElemType> *root;
    BiNode<ElemType> *Creat(BiNode<ElemType> *bt);
    void Release(BiNode<ElemType> *bt);
    void PreOrder(BiNode<ElemType> *bt);
    void InOrder(BiNode<ElemType> *bt);
    void PostOrder(BiNode<ElemType> *bt);
    void LevelOrder(BiNode<ElemType> *bt);
    int Depth(BiNode<ElemType> *bt);
    int Count(BiNode<ElemType> *bt);
    int CountLeaf(BiNode<ElemType> *bt);
    void PrintLeaf(BiNode<ElemType> *bt);
    int SmallestDepth(BiNode<ElemType> *bt);
    int IsCompleteBiTree(BiNode<ElemType> *bt);
    int IsCheck(BiNode<ElemType> *lchild , BiNode<ElemType> *rchild);
    int IsStructureSymmetric(BiNode<ElemType> *bt);
    int IsL_R_Check(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild);
    //二叉树第k层的结点个数和叶子结点个数
    int GetNodesNumberOfKthLevle(BiNode<ElemType> *bt,int k);
    int GetLeafNodesNumberOfKthLevel(BiNode<ElemType> *bt,int k);
    //打印二叉树第k层的结点和叶子结点
    void PrintNodesOfKthLevel(BiNode<ElemType> *bt,int k);
    void PrintLeafNodesOfKthLevel(BiNode<ElemType> *bt,int k);
public:
    BiTree(){root = Creat(root);}
    ~BiTree(){
        Release(root);
    }
    void PreOrder(){
        PreOrder(root);
    }
    void InOrder(){
        InOrder(root);
    }
    void PostOrder(){
        PostOrder(root);
    }
    void LevelOrder(){
        LevelOrder(root);
    }
    int Depth(){
        return Depth(root);
    }
    int Count(){
        return Count(root);
    }
    int CountLeaf(){
        return CountLeaf(root);
    }
    void PrintLeaf(){
        PrintLeaf(root);
    }
    int SmallestDepth(){
        return SmallestDepth(root);
    }
    int IsCompletBiTree(){
        return IsCompleteBiTree(root);
    }
    int IsStructureSymmetric(){
        return IsStructureSymmetric(root);
    }
    int IsL_R_Check(){
        return IsL_R_Check(root->lchild, root->rchild);
    }
    //根据前序和中序序列构造二叉树  有参构造函数
    BiTree(ElemType *preOrder, ElemType *inOrder, int len) {
        root = Rebuild(preOrder, inOrder, len);
    }
    BiNode<ElemType>* Rebuild(ElemType *preOrder,ElemType *inOrder,int n);
    //二叉树第k层的结点个数和叶子结点个数
    int GetNodesNumberOfKthLevle(int k){
        return GetNodesNumberOfKthLevle(root, k);
    };
    int GetLeafNodesNumberOfKthLevel(int k){
        return GetLeafNodesNumberOfKthLevel(root, k);
    };
    //打印二叉树第k层的结点和叶子结点
    void PrintNodesOfKthLevel(int k){
        PrintNodesOfKthLevel(root, k);
    };
    void PrintLeafNodesOfKthLevel(int k){
        PrintLeafNodesOfKthLevel(root, k);
    };
};



#endif /* BiTree_hpp */

.m文件,因为我的不能设置成.m文件,只好用另一个cpp文件来代替了

#include "BiTree.hpp"
#include "CirQueue.cpp"
#include <iostream>
using namespace std;

//前序遍历
template <class Elemtype>
void BiTree<Elemtype>::PreOrder(BiNode<Elemtype> *bt){
    if (bt == NULL) {
        return;
    }
    else{
        cout << bt->data << " ";
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
    }
}
//中序遍历
template <class Elemtype>
void BiTree<Elemtype>::InOrder(BiNode<Elemtype> *bt){
    if(bt==NULL){
        return;
    }
    else{
        InOrder(bt->lchild);
        cout << bt->data << " ";
        InOrder(bt->rchild);
    }
}
//后序遍历
template <class ElemType>
void BiTree<ElemType>::PostOrder(BiNode<ElemType> *bt){
    if (bt == NULL) {
        return;
    }
    else{
        PostOrder(bt->lchild);
        PostOrder(bt->rchild);
        cout << bt->data << "";
    }
}
//层序遍历
template <class ElemType>
void BiTree<ElemType>::LevelOrder(BiNode<ElemType> *bt){
    const int MaxSize = 100;
    //采用顺序队列,假设不会发生溢出
    int front = 0, rear = 0;
    BiNode<ElemType> *Q[MaxSize],*q;
    if (bt == NULL) {
        return;
    }
    else{
        Q[rear++] = bt;                     //bt入队
        //队列非空时循环
        while (front!=rear) {
            q = Q[front++];                 //队头出队
            cout << q->data << " ";         //访问队头
            if (q->lchild != NULL) {        //如果队头有左孩子,则左孩子入队
                Q[rear++] = q->lchild;
            }
            if (q->rchild !=NULL) {         //如果队头有右孩子,则右孩子入队
                Q[rear++] = q->rchild;
            }
        }
    }
}
//构造函数
template <class ElemType>
BiNode<ElemType> *BiTree<ElemType>::Creat(BiNode<ElemType> *bt){
    ElemType ch;
//    cout << "请输入创建一棵二叉树的节点数据:" << endl;
    cin >> ch;
    if (ch == '*'){
        return NULL;
    }
    else{
        bt = new BiNode<ElemType>;
        bt->data = ch;
        bt->lchild = Creat(bt->lchild);
        bt->rchild = Creat(bt->rchild);
    }
    return bt;
}

//析构函数
template <class ElemType>
void BiTree<ElemType>::Release(BiNode<ElemType> *bt){
    if (bt != NULL) {
        Release(bt->lchild);
        Release(bt->rchild);
        delete bt;
    }
}

//求二叉树的深度
template <class ElemType>
int BiTree<ElemType>::Depth(BiNode<ElemType> *bt){
    if (bt == NULL) {
        return 0;
    }
    else{
        int dep1 = Depth(bt->lchild);
        int dep2 = Depth(bt->rchild);
        return (dep1>dep2)?(dep1+1):(dep2+1);
    }
}

//求二叉树的节点个数
int countNode = 0;
template <class ElemType>
int BiTree<ElemType>::Count(BiNode<ElemType> *bt){
    if (bt != NULL) {
        Count(bt->lchild);
        countNode++;
        Count(bt->rchild);
    }
    return countNode;
}


//求二叉树的叶子节点个数
int countLeaf = 0;
template <class ElemType>
int BiTree<ElemType>::CountLeaf(BiNode<ElemType> *bt){
    if (bt != NULL) {
        if (bt->lchild == NULL && bt->rchild == NULL) {
            
            countLeaf++;
        }
        CountLeaf(bt->lchild);
        CountLeaf(bt->rchild);
    }
    return countLeaf;
}

//输出二叉树的叶子结点
template<class ElemType>
void BiTree<ElemType>::PrintLeaf(BiNode<ElemType> *bt){
    if(bt != NULL){
        if (bt->lchild == NULL && bt->rchild == NULL) {
            cout << bt->data << " " ;
        }
        PrintLeaf(bt->lchild);
        PrintLeaf(bt->rchild);
    }
}
//求二叉树的最小深度
template <class ElemType>
int BiTree<ElemType>::SmallestDepth(BiNode<ElemType> *bt){
    if(bt == NULL)
        return 0;
    if(bt->lchild == NULL)
        return SmallestDepth(bt->rchild) + 1;
    if(bt->rchild == NULL)
        return SmallestDepth(bt->lchild) + 1;
    int m = SmallestDepth(bt->lchild) + 1;
    int n = SmallestDepth(bt->rchild) + 1;
    return m < n ? m:n;
}
//判断二叉树是否为完全二叉树
template <class ElemType>
int BiTree<ElemType>::IsCompleteBiTree(BiNode<ElemType> *bt){
    CirQueue<BiNode<ElemType> *> Q;
    BiNode<ElemType> *p;
    if(bt == NULL) return 1;
    Q.EnQueue(bt);
    //当出队的队头指针不为空时,将其左、右指针入队
    while ( (p = Q.DeQueue()) != NULL) {
        Q.EnQueue(p->lchild);
        Q.EnQueue(p->rchild);
    }
    //当遇到空指针时,判断队列中是否有非空指针
    //如果有,则不是完全二叉树,没有,则为完全二叉树
    while(!Q.Empty()){
        p = Q.DeQueue();
        if (p != NULL){
            return 0;
        }
    }
    return 1;
}
//判断二叉树左右子树是否结构对称
template <class ElemType>
int BiTree<ElemType>::IsCheck(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild){
    if(lchild == NULL && rchild == NULL){
        return 1;
    }
    if(lchild == NULL || rchild == NULL){
        return 0;
    }
    return IsCheck(lchild->lchild, rchild->rchild) && IsCheck(lchild->rchild, rchild->lchild);
}
//判断二叉树是否结构对称
template <class ElemType>
int BiTree<ElemType>::IsStructureSymmetric(BiNode<ElemType> *bt){
    if(bt == NULL){
        return 1;
    }
    return IsCheck(bt->lchild,bt->rchild);
}
//判断二叉树是否对称
template <class ElemType>
int BiTree<ElemType>::IsL_R_Check(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild){
    if(lchild == NULL && rchild == NULL){
        return 1;
    }
    if(lchild == NULL || rchild == NULL){
        return 0;
    }
    //此处与判断结构性对称不同
    if (lchild->data != rchild->data) {
        return  0;
    }
    return IsL_R_Check(lchild->lchild, rchild->rchild) && IsL_R_Check(lchild->rchild, rchild->lchild);
}
/*根据前序遍历和中序遍历重建二叉树*/
template <class ElemType>
BiNode<ElemType> * BiTree<ElemType>::Rebuild(ElemType *preOrder, ElemType *inOrder, int n){
    if (n == 0) {
        return NULL;
    }
    //获得前序遍历的第一个节点
    ElemType c = preOrder[0];
    //创建根节点
    BiNode<ElemType> *node = new BiNode<ElemType>;
    node->data = c;
    node->lchild = NULL;
    node->rchild = NULL;
    int i;
    //在中序遍历序列中寻找根节点的位置
    for (i = 0; i < n && inOrder[i] != c; i++) {
    }
    //左子树节点的个数
    int lenLeft = i;
    //右子树节点个数
    int lenRight = n - i - 1;
    //左子树不为空,递归重建左子树
    if (lenLeft > 0) {
        node->lchild = Rebuild(&preOrder[1], &inOrder[0], lenLeft);
    }
    //右子树不为空,递归重建右子树
    if (lenRight > 0) {
        node->rchild = Rebuild(&preOrder[lenLeft+1],&inOrder[lenLeft+1],lenRight);
    }
    return node;
}

//二叉树第k层的结点个数和叶子结点个数
template <class ElemType>
int BiTree<ElemType>::GetNodesNumberOfKthLevle(BiNode<ElemType> *bt, int k){
    if (bt == NULL || k < 1) {
        return 0;
    }
    if (k == 1) {
        return 1;
    }
    return GetNodesNumberOfKthLevle(bt->lchild, k - 1) + GetNodesNumberOfKthLevle(bt->rchild, k-1);
}

template <class ElemType>
int BiTree<ElemType>::GetLeafNodesNumberOfKthLevel(BiNode<ElemType> *bt, int k){
    if (bt == NULL || k < 1) {
        return 0;
    }
    else {
        if (k == 1) {
            if (bt->lchild == NULL && bt->rchild == NULL) return 1;
            else return 0;
        }
        else if(k > 1){
            return GetLeafNodesNumberOfKthLevel(bt->lchild, k-1) + GetLeafNodesNumberOfKthLevel(bt->rchild, k-1);
        }
    }
    return 1;
}

//打印二叉树第k层的结点和叶子结点
template <class ElemType>
void BiTree<ElemType>::PrintNodesOfKthLevel(BiNode<ElemType> *bt, int k){
    if (bt == NULL || k < 1) {
        return;
    }
    if(k == 1){
        cout << bt->data<<" ";
    }
    PrintNodesOfKthLevel(bt->lchild, k - 1);
    PrintNodesOfKthLevel(bt->rchild, k - 1);
}

template <class ElemType>
void BiTree<ElemType>::PrintLeafNodesOfKthLevel(BiNode<ElemType> *bt, int k){
    if (bt == NULL || k < 1) return ;
    if (bt != NULL ){
        if (k == 1){
            if(bt->lchild == NULL && bt->rchild == NULL)
                cout << bt->data<< " ";}
        else if (k > 1){
            PrintLeafNodesOfKthLevel(bt->lchild, k-1);
            PrintLeafNodesOfKthLevel(bt->rchild, k-1);
        }
    }
}

队列的类模版(部分):

#ifndef CIRQUEUE_H
#define CIRQUEUE_H

const int QueueSize = 100; /*定义循环队列的容量*/
template <class ElemType> /*定义模板类CirQueue*/
class CirQueue{
public:
    CirQueue(); /*构造函数,循环队列的初始化*/
    void EnQueue(ElemType x); /*入队操作*/
    ElemType DeQueue(); /*出队操作*/
    int Empty(); /*判断队列是否为空,若为空返回1,否则返回0*/
private:
    ElemType data[QueueSize]; /*存放队列元素的数组*/
    int front, rear; /*队头,队尾指针*/
};
#endif

.cpp(.m)文件

#include <iostream>
using namespace std;
#include "CirQueue.hpp"

template <class ElemType>
CirQueue<ElemType>::CirQueue() {
    front = QueueSize-1;
    rear = QueueSize-1;
}

template <class ElemType>
void CirQueue<ElemType>::EnQueue(ElemType x) {
    if((rear + 1) % QueueSize == front)
        throw "循环队列已满,溢出!";
    rear = (rear + 1) % QueueSize;
    data[rear] = x;
}

template <class ElemType>
ElemType CirQueue<ElemType>::DeQueue() {
    if(rear == front)
        throw "循环队列为空!";
    front = (front + 1) % QueueSize;
    return data[front];
}

template <class ElemType>
int CirQueue<ElemType>::Empty() {
    if(front == rear)
        return 1;
    else
        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值