二叉树的实现

binTreeNode.h

#pragma once
# include<iostream>
template <typename T>
class binTreeNode
{
public:
    binTreeNode() = default;
    binTreeNode(const T&t):data(t),lChild(NULL),rChild(NULL)
    {}

    T data;
    binTreeNode *lChild, *rChild;
};

binTree.h

#pragma once
# include"binTreeNode.h"
#include<iostream>
# include<string>
# include"myQuene.h"
# include"myStack.h"
using namespace std;

template <typename T>
class binTree
{
public:
    //构造函数:建立二叉树,元素为#时表示为该节点为空
    binTree() = default;

    ~binTree();//析构函数

    binTree(const binTree&t);

    void levelCreate();//按层次建立二叉树
    void visit(binTreeNode<T> *node);//访问节点

    void inTraver(binTreeNode<T> *p);//中序遍历
    void prevTraver(binTreeNode<T> *p);//先序遍历
    void postTraver(binTreeNode<T> *p);//后序遍历
    void inTraver1();//中序遍历(非递归)
    void prevTraver1();//先序遍历(非递归)
    void postTraver1();//后序遍历(非递归)
    void levelTraver();//层次遍历

    int countOfNode(binTreeNode<T> *);//树的节点个数
    int height(binTreeNode<T> *);   //树的高度

    binTreeNode<T>* &getRoot() { return root; }//返回根节点
    void destroy(binTreeNode<T> *);

private:
    binTreeNode<T> *root;//二叉树的根节点
};

template<typename T>
binTree<T>::~binTree()
{
    if (root)
        delete root;

}

template<typename T>
void binTree<T>::levelCreate()//按层次建立树
{
    T elem;

    int i = 1;//i表示正在处理的节点的序号,初始化为处理第一个节点
    binTreeNode<T>** (arr[100]) = {};
    /*
      保存指向每个节点的指针,比如建立下面这样的树(括号左边是序号,括号里面节点元素,以整型为例,输入
     0表示为空节点):

               1(1)
          2(2)        3(3)
       4(0)   5(4)   6(5)  7(6)

       输入时应输入:1 2 3 0 4 5 6
       比如处理节点元素为4时,要改变其双亲节点,对吧,令其双亲的rChild指针指向正在处理的节点,所以
       我就定义一个数组保存指针,可能空间开销比较大
    */


    while (cin >> elem)
    {
        if (i == 1)//第一个元素,处理根节点
        {
            arr[i - 1] = &root;
            root = new binTreeNode<T>(elem);
            i++;
            continue;
        }

        if (elem == 0||elem=='0')//如果是空节点
        {
            if (i % 2 == 0&&(arr[i/2-1]))//能够被2整除,那么该节点为其双亲的左孩子,并且其双亲
                //应该存在,才可以令其双亲的左孩子指针为空
                ((*arr[i / 2-1]))->lChild = NULL;
            else if(arr[i/2-1])//否咋是其右孩子
                ((*arr[i / 2-1]))->rChild = NULL;

            arr[i - 1] = NULL;//此节点为空
            i++;
            continue;
        }

        arr[i - 1] = new binTreeNode<T> *;//节点不位空
        binTreeNode<T> *temp = new binTreeNode<T>(elem);
        if (i % 2 == 0)
            (*arr[i / 2-1])->lChild = temp;//同理
        else (*arr[i / 2-1])->rChild = temp;
        *arr[i - 1] = temp;//保存节点指针
        i++;
    }
}

template <typename T>
void binTree<T>::visit(binTreeNode<T> *node)//访问元素
{
    cout << node->data<<" ";
}

template <typename T>
void binTree<T>::inTraver(binTreeNode<T> *p)//中序遍历
{
    if (p)
    {   
        inTraver(p->lChild);
        visit(p);
        inTraver(p->rChild);
    }
}

template <typename T>
void binTree<T>::prevTraver(binTreeNode<T> *p)//先序遍历
{
    if (p)
    {
        visit(p);
        prevTraver(p->lChild);
        prevTraver(p->rChild);
    }
}

template <typename T>
void binTree<T>::postTraver(binTreeNode<T> *p)//后序遍历
{
    if (p)
    {
        postTraver(p->lChild);
        postTraver(p->rChild);
        visit(p);
    }
}

template<typename T>
void binTree<T>::inTraver1()//中序遍历(非递归)
{
    myStack<binTreeNode<T> *> s;
    binTreeNode<T> *t=root;

    while (t || !s.empty())//当t不为空或s不为空时
    {
        if (t)//如果t不为空
        {
            s.push(t);//保留t
            t = t->lChild;
        }
        else
        {
            s.pop(t);
            visit(t);
            t = t->rChild;
        }

    }

}

template<typename T>
void binTree<T>::prevTraver1()//先序遍历(非递归)
{
    myStack<binTreeNode<T> *> s;
    binTreeNode<T>* t=root;
    while (t || !s.empty())
    {
        if (t)
        {
            visit(t);
            s.push(t);
            t = t->lChild;
        }

        else
        {
            s.pop(t);
            t = t->rChild;
        }
    }
}

template<typename T>
void binTree<T>::postTraver1()//后序遍历(非递归)
{
    myStack<binTreeNode<T> *> s;
    myStack<T> s1;
    binTreeNode<T>* t = root;
    while (t || !s.empty())
    {
        if (t)
        {
            s1.push(t->data);
            s.push(t);
            t = t->rChild;
        }

        else
        {
            s.pop(t);
            t = t->lChild;
        }
    }
    T temp;
    while (!s1.empty())
    {
        s1.pop(temp);
        cout << temp << " ";
    }
}

template <typename T>
void binTree<T>::levelTraver()
{
    myQuene<binTreeNode<T> *> q(30);
    binTreeNode<T> *t;
    if (root)
    {
        visit(root);
        q.in(root); 
    }
    while (!q.empty())
    {
        q.out(t);
        if (t->lChild)
        {
            visit(t->lChild);
            q.in(t->lChild);
        }
         if (t->rChild)
        {
            visit(t->rChild);
            q.in(t->rChild);
        }
    }
}

template<typename T>
int binTree<T>::countOfNode(binTreeNode<T> *n)
{
    //int count = 0;
    if (n)
    {
        countOfNode(n->lChild);
        return countOfNode(n->lChild)+countOfNode(n->rChild)+1;
    }
    else return 0;
}

template<typename T>
int binTree<T>::height(binTreeNode<T> *n)   //树的高度
{
    if (n)
    {
        int h1 = height(n->lChild);
        int h2 = height(n->rChild);
        if (h1 > h2)
            return h1 + 1;
        return h2 + 1;
    }
    return 0;
}

template<typename T>
void binTree<T>::destroy(binTreeNode<T> *n)
{
    binTreeNode<T> *l,*r;
    if (n)
    {
        l = n->lChild;
        r = n->rChild;
        delete n;
        destroy(l);
        destroy(r);
    }
    root = NULL;
}

main.cpp

# include"BinTree.h"
# include<iostream>

using namespace std;

int main()
{
    binTree<char> myBinTree;

    cout << "建立二叉树,元素为0时表示为该节点为空(元素为int型):" << endl;


    myBinTree.levelCreate();
    auto &p = myBinTree.getRoot();

    cout << endl << "先序遍历为:";
    myBinTree.prevTraver(p);

    cout <<endl<<"中序遍历为:" ;
    myBinTree.inTraver(p);

    cout << endl << "后序遍历为:";
    myBinTree.postTraver(p);

    cout << endl << "层次遍历为:";
    myBinTree.levelTraver();

    cout <<endl<<endl<< "树的节点个数为:" << myBinTree.countOfNode(p) << endl;

    cout << "树的高度为:" << myBinTree.height(p) << endl;

    cout << endl << "先序非递归遍历:";
    myBinTree.prevTraver1();

    cout <<endl<< "中序非递归遍历:";
    myBinTree.inTraver1();

    cout << endl << "后序非递归遍历:";
    myBinTree.postTraver1();

    cout <<endl<< "销毁二叉树后:" << endl;
    myBinTree.destroy(p);
    myBinTree.levelTraver();
    /*cout << endl;

    cout << endl<<endl;*/
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值