详细二叉树实现c++

前言

当初学数据结构遗留下来的代码。不过代码中空指针建议用nullptr, 而不要用0。当初没有优化。



代码

#include <iostream>
#include<stack>
#include<queue>
using namespace std;


//二叉树结点
template<class T>
struct BinTreeNode
{
    
    
    T data;
    BinTreeNode* leftchild, * rightchild;
    BinTreeNode() : leftchild(0), rightchild(0) {
    
    }
    BinTreeNode(T x, BinTreeNode* l = 0, BinTreeNode * r = 0) : data(x), leftchild(l), rightchild(r) {
    
    }
};

//后序非递归遍历用到的结构
template<class T>
struct stkNode {
    
    
    BinTreeNode<T>* ptr;
    int tag; //0代表左,1代表右
    stkNode(BinTreeNode<T>* N = 0) : ptr(N), tag(0) {
    
    }
};

template<class T>
class BinaryTree {
    
    
public:
    BinaryTree() : root(0) {
    
    }
    ~BinaryTree() {
    
    }

    //建树
    void Create();
    void Create(BinTreeNode<T>*& BT, T endValue);
    //删除树
    void destroy();
    void destroy(BinTreeNode<T>* subTree);

    //前序,中序,后序递归遍历算法
    void PreOrder(void(*visti)(BinTreeNode<T>* p)) const;
    void InOrder(void(*visit)(BinTreeNode<T>* p)) const;
    void PostOrder(void (*visit)(BinTreeNode<T>* p)) const;
    //重载前序,中序,后序递归排序算法
    void PreOrder(BinTreeNode<T>* subTree, void (*visit)(BinTreeNode<T>* p)) const;
    void InOrder(BinTreeNode<T>* subTree, void (*visit)(BinTreeNode<T>* p)) const;
    void PostOrder(BinTreeNode<T>* subTree, void (*visit)(BinTreeNode<T>* p)) const;
    //前序,中序,后序非递归算法
    void PreOrderNonRecursion(void(*visit)(BinTreeNode<T>* p));
    void InOrderNonRecursion(void(*visit)(BinTreeNode<T>* p));
    void PostOrderNonRecursion(void(*visit)(BinTreeNode<T>* p));

    //层次遍历
    void LevelOrder(void (*visit)(BinTreeNode<T>* p));

    //求树高
    int Height() const;
    int Height(BinTreeNode<T>* subTree) const;
    int HeightNoRecursion();

    //求节点个数
    int Size() const;                       //从根开始
    int Size(BinTreeNode<T>* subTree) const;      //前序遍历顺序
    int SizeNonRecursionByLevelOrder();     //非递归方法,层次遍历顺序
    int SizeNonRecursionByPreOrder();       //非递归方法,前序遍历顺序

    //求叶子结点总数
    int LeavesSize() const;   //从根开始
    int LeavesSize(BinTreeNode<T>* t) const;   //前序遍历顺序
    int LeavesSizeNonRecursionByLevelOrder();
    int LeavesSizeNonRecursionByPreOrder();

    //广义表输出二叉树
    void PrintBinTree();
    void PrintBinTree(BinTreeNode<T>* BT);

private:
    BinTreeNode<T>* root;
};










//

//从根开始建立树
template<class T>
void BinaryTree<T>::Create()
{
    
    
    cout << "请输入结束的标志" << endl;
    T endValue;
    cin >> endValue;
    cout << "请输入二叉树结点的值 (0结束)" << endl;
    Create(root, endValue);
}


//前序顺序建立二叉树
template<class T>
void BinaryTree<T>::Create(BinTreeNode<T>*& BT, T endValue)
{
    
    

    T x;
    cin >> x;
    if (x == endValue)
    {
    
    
        BT = 0;
    }
    else
    {
    
    
        BT = new BinTreeNode<T>(x);
        Create(BT->leftchild, endValue);
        Create(BT->rightchild, endValue);
    }
}


//从根开始删除
template<class T>
void BinaryTree<T>::destroy()
{
    
    
    destroy(root);
}

//删除以subtree为根的树
template<class T>
void BinaryTree<T>::destroy(BinTreeNode<T>* subTree)
{
    
    
    if (subTree != 0)
    {
    
    
        destroy(subTree->leftchild);
        destroy(subTree->rightchild);
        delete subTree;
    }
    root = 0;  //不然删完遍历会报错
}






//

//前序,中序,后序递归遍历算法
template<class T>
void BinaryTree<T>::PreOrder(void (*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    PreOrder(root, visit);
}



template<class T>
void BinaryTree<T>::InOrder(void (*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    InOrder(root, visit);
}



template<class T>
void BinaryTree<T>::PostOrder(void (*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    PostOrder(root, visit);
}




//前序,中序,后序遍历重载

template<class T>
void BinaryTree<T>::PreOrder(BinTreeNode<T>* subTree, void (*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (subTree != 0)
    {
    
    
        visit(subTree);
        PreOrder(subTree->leftchild, visit);
        PreOrder(subTree->rightchild, visit);
    }
}


template<class T>
void BinaryTree<T>::InOrder(BinTreeNode<T>* subTree, void (*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (subTree != 0)
    {
    
    
        InOrder(subTree->leftchild, visit);
        visit(subTree);
        InOrder(subTree->rightchild, visit);
    }
}
template<class T>
void BinaryTree<T>::PostOrder(BinTreeNode<T>* subTree, void(*visit)(BinTreeNode<T>* p)) const
{
    
    
    if (subTree != 0)
    {
    
    
        PostOrder(subTree->leftchild, visit);
        PostOrder(subTree->rightchild, visit);
        visit(subTree);
    }
}






//非递归前序,中序,后序遍历算法
template<class T>
void BinaryTree<T>::PreOrderNonRecursion(void(*visit)(BinTreeNode<T>* p))
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    stack<BinTreeNode<T>*> S;
    BinTreeNode<T>* p = root;
    do
    {
    
    
        //一直往左,访问并记录结点以便返回
        while (p != 0)
        {
    
    
            S.push(p);
            visit(p);
            p = p->leftchild;
        }
        if (!S.empty())
        {
    
    
            p = S.top();
            S.pop();
            p = p->rightchild;
        }
    } while (p != 0 || !S.empty());
    cout << endl;
}


template<class T>
void BinaryTree<T>::InOrderNonRecursion(void(*visit)(BinTreeNode<T>* p))
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    stack<BinTreeNode<T>*> S;
    BinTreeNode<T>* p = root;
    do {
    
    
        //一直往左,访问并记录结点以便返回
        while (p != 0)
        {
    
    
            S.push(p);
            p = p->leftchild;
        }
        if (!S.empty())
        {
    
    
            p = S.top();
            S.pop();
            visit(p);
            p = p->rightchild;
        }
    } while (p != 0 || !S.empty());
    cout << endl;
}


template<class T>
void BinaryTree<T>::PostOrderNonRecursion(void(*visit)(BinTreeNode<T>* p))
{
    
    
    if (root == 0)
    {
    
    
        cout << "该树为空" << endl;
        return;
    }
    stack<stkNode<T>> S;
    stkNode<T> w;
    BinTreeNode<T>* p = root;
    do
    {
    
    
        while (p != 0)
        {
    
    
            w.ptr = p;
            w.tag = 0;
            S.push(w);
            p = p->leftchild;
        }
        bool continuing = true;
        while (continuing && !S.empty())
        {
    
    
            w = S.top();
            S.pop();
            p = w.ptr;
            switch (w.tag)
            {
    
    
                case 0:
                    w.tag = 1;
                    S.push(w);
                    continuing = false; //停止这个while循环,让它去找最左的左子树0
                    p = p->rightchild;
                    break;
                case 1:
                    visit(p);
                    break;
            }
        }
    } while (!S.empty());
    cout << endl;
}



//层次遍历
template<class T>
void BinaryTree<T>::LevelOrder(void(*visit)(BinTreeNode<T>* p))
{
    
    
    queue<BinTreeNode<T>*> Q;
    BinTreeNode<T>* p = root;
    Q.push(p);//指向根节点的指针入队
    while (!Q.empty())
    {
    
    
        p = Q.front();
        Q.pop();
        visit(p);
        if (p->leftchild != 0)
        {
    
    
            Q.push(p->leftchild);
        }

        if (p->rightchild != 0)
        {
    
    
            Q.push(p->rightchild);
        }
    }
}






//求树高
template<class T>
int BinaryTree<T>::Height() const
{
    
    
    return Height(root);
}


template<class T>
int BinaryTree<T>::Height(BinTreeNode<T>* subTree) const
{
    
    
    if (subTree == 0)
    {
    
    
        return 0;
    }
    int leftchildHeight = Height(subTree->leftchild);
    int rightchildHeight = Height(subTree->rightchild);
    return (leftchildHeight > rightchildHeight) ? leftchildHeight + 1 : rightchildHeight + 1;
}


//非递归求树高,层次遍历顺序
template<class T>
int BinaryTree<T>::HeightNoRecursion()
{
    
    
    int depth = 0;
    BinTreeNode<T>* p = root;
    queue<BinTreeNode<T>*> q;
    q.push(p);  //根指针入队
    while (!q.empty())
    {
    
    
        depth++;
        int width = q.size();
        for (int i = 0; i < width; i++)
        {
    
    
            p = q.front();
            q.pop();
            if (p->leftchild != 0)
                q.push(p->leftchild);
            if (p->rightchild != 0)
                q.push(p->rightchild);
        }
    }
    return depth;
}






//求结点个数
template<class T>
int BinaryTree<T>::Size() const
{
    
    
    return Size(root);
}


template<class T>
int BinaryTree<T>::Size(BinTreeNode<T>* subTree) const
{
    
    
    if (subTree == 0)
        return 0;
    return 1 + Size(subTree->leftchild) + Size(subTree->rightchild);
}




//非递归求节点个数,层次遍历顺序
template<class T>
int BinaryTree<T>::SizeNonRecursionByLevelOrder()
{
    
    
    //如果树根为空,则节点数为0
    if (root == 0)
        return 0;
    //如果不空,则可以执行下面的操作
    int size = 1;  //至少有根节点
    BinTreeNode<T>* p = root;
    queue<BinTreeNode<T>*> Q;
    Q.push(p);  根指针入队
    while (!Q.empty())
    {
    
    
        int width = Q.size();  //获取当前层次宽度,也就是知道下一层次的所有节点个数
        for (int i = 0; i < width; i++)
        {
    
    
            p = Q.front();     //获取队顶元素
            Q.pop();          //弹出队顶元素
            if (p->leftchild != 0)
            {
    
    
                size++;
                Q.push(p->leftchild);
            }
            if (p->rightchild != 0)
            {
    
    
                size++;
                Q.push(p->rightchild);
            }
        }
    }
    return size;
}



template<class T>
int BinaryTree<T>::SizeNonRecursionByPreOrder()
{
    
    
    if (root == 0)
        return 0;
    stack<BinTreeNode<T>*> S;
    BinTreeNode<T>* p = root;
    int size = 0;  //结点计数器
    do
    {
    
    
        while (p != 0)
        {
    
    
            S.push(p);
            size++;
            p = p->leftchild;
        }
        if (!S.empty())
        {
    
    
            p = S.top();
            S.pop();
            p = p->rightchild;
        }
    } while (p != 0 || !S.empty());
    return size;
}



//求叶子结点数目
template<class T>
int BinaryTree<T>::LeavesSize() const
{
    
    
    return LeavesSize(root);
}



template<class T>
int BinaryTree<T>::LeavesSize(BinTreeNode<T>* t) const
{
    
    
    if (t == 0)
        return 0;
    if (t->leftchild == 0 && t->rightchild == 0)
        return 1;
    return LeavesSize(t->leftchild) + LeavesSize(t->rightchild);
}





template<class T>
int BinaryTree<T>::LeavesSizeNonRecursionByLevelOrder()
{
    
    
    //如果树根为空,则节点数为0
    if (root == 0)
        return 0;
    //初始时叶子结点计数器置0
    int size = 0;
    BinTreeNode<T>* p = root;
    queue<BinTreeNode<T>*> Q;
    Q.push(p);   //根指针入队
    while (!Q.empty())
    {
    
    
        int width = Q.size();       //获取当前层次宽度,也就是知道下一层次的所有节点个数
        for (int i = 0; i < width; i++)
        {
    
    
            p = Q.front();       //获取队顶元素
            Q.pop();			//弹出队顶元素
            if (p->leftchild == 0 && p->rightchild == 0)
            {
    
    
                size++;
            }
            else
            {
    
    
                if (p->leftchild != 0)
                    Q.push(p->leftchild);
                if (p->rightchild != 0)
                    Q.push(p->rightchild);
            }
        }
    }
    return size;
}



template<class T>
int BinaryTree<T>::LeavesSizeNonRecursionByPreOrder()
{
    
    
    if (root == 0)
        return 0;
    stack<BinTreeNode<T>*>S;
    BinTreeNode<T>* p = root;
    int size = 0;
    do {
    
    
        while (p != 0)
        {
    
    
            S.push(p);
            //叶子结点呢
            if (p->leftchild == 0 && p->rightchild == 0)
            {
    
    
                size++;
                break;
            }
            p = p->leftchild;
        }
        if (!S.empty())
        {
    
    
            p = S.top();
            S.pop();
            p = p->rightchild;
        }
    } while (p != 0 || !S.empty());
    return size;
}




//广义表输出二叉树
template<class T>
void BinaryTree<T>::PrintBinTree()
{
    
    
    PrintBinTree(root);
}



template<class T>
void BinaryTree<T>::PrintBinTree(BinTreeNode<T>* BT)
{
    
    
    if (BT != 0)
    {
    
    
        cout << BT->data;
        if (BT->leftchild != 0 || BT->rightchild != 0)
        {
    
    
            cout << "(";
            PrintBinTree(BT->leftchild);  // 递归输出左子树
            if (BT->rightchild != 0)
            {
    
    
                cout << ",";
                PrintBinTree(BT->rightchild); // 递归输出右子树
            }
            cout << ")";
        }
    }
}




















//输出结点data值的函数
template<class T>
void PrintData(BinTreeNode<T>* p)
{
    
    
    cout << p->data << " ";
}





int main()
{
    
    
    BinaryTree<char> a;
    a.Create();

    cout << endl << endl;
    cout << "前序递归遍历" << endl;
    a.PreOrder(PrintData);

    cout << endl << endl;
    cout << "中序递归遍历" << endl;
    a.InOrder(PrintData);

    cout << endl << endl;
    cout << "后序递归遍历" << endl;
    a.PostOrder(PrintData);

    cout << endl << endl << endl;
    cout << "前序非递归遍历" << endl;
    a.PreOrderNonRecursion(PrintData);

    cout << endl;
    cout << "中序非递归遍历" << endl;
    a.InOrderNonRecursion(PrintData);

    cout << endl;
    cout << "后序非递归遍历" << endl;
    a.PostOrderNonRecursion(PrintData);

    cout << endl;
    cout << "层次遍历" << endl;
    a.LevelOrder(PrintData);

    cout << endl;
    cout << "递归求树的高度" << endl;
    cout << "height: " << a.Height();

    cout << endl << endl;
    cout << "非递归求树的高度" << endl;
    cout << "height: " << a.HeightNoRecursion();

    cout << endl << endl << endl << endl;
    cout << "递归求结点个数" << endl;
    cout << "size: " << a.Size();

    cout << endl << endl;
    cout << "层次顺序非递归求结点个数" << endl;
    cout << "size: " << a.SizeNonRecursionByLevelOrder();

    cout << endl << endl;
    cout << "前序顺序非递归求结点个数" << endl;
    cout << "size: " << a.SizeNonRecursionByPreOrder();


    cout << endl << endl;
    cout << "***************************************************" << endl;
    cout << endl << endl;
    cout << "递归求叶子结点总数" << endl;
    cout << "leavesSize: " << a.LeavesSize() << endl;

    cout << endl << endl;
    cout << "层次顺序非递归方法求叶子结点总数" << endl;
    cout << "leavesSize: " << a.LeavesSizeNonRecursionByLevelOrder() << endl;

    cout << endl << endl;
    cout << "前序顺序非递归方法求叶子结点总数" << endl;
    cout << "leavesSize: " << a.LeavesSizeNonRecursionByPreOrder() << endl;


    cout << endl << endl;
    cout << "广义表输出" << endl;
    a.PrintBinTree();

    cout << endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_43850253/article/details/110937462