简单链式二叉树(C++模版技术实现)

下面代码仅供本人复习数据结构所用,实用性N低,各位飘过吧~~哈哈:>

//
// C++ 模版技术实现简单二叉树.
//
 
#include <cstdlib>
#include <cstring>
#include <iostream>
 
// 二叉树类模版前置声明
template <typename T> class BinaryTree;
 
//
// 二叉树节点类模版.
//
template <typename T>
class Node
{
    friend class BinaryTree<T>;
private:
    T _data;
    Node<T> *_pLeftChild, *_pRightChild;
     
public:
    Node(const T &data)
        : _data(data)
        , _pLeftChild(NULL)
        , _pRightChild(NULL)
    { NULL; }
};
 
//
// 二叉树类模版
//
template <typename T>
class BinaryTree
{
private:
    Node<T> *_pRoot;
     
private:
    void _create(Node<T> **ppRoot, T **ppArray, int *piSize, const T &delim);
    void _clear(Node<T> *pRoot);
    void _preOrder(Node<T> *pRoot) const;
    void _inOrder(Node<T> *pRoot) const;
    void _postOrder(Node<T> *pRoot) const;
    size_t _height(Node<T> *pRoot) const;
    size_t _count(Node<T> *pRoot) const;
     
public:
    // 遍历类型.
    enum TraversalType {
        PRE_ORDER,
        IN_ORDER,
        POST_ORDER 
    };
     
public:
    BinaryTree(T *array, int size, const T &delim);
    ~BinaryTree(void);
    void traversal(const TraversalType type) const;
    size_t getHeight(void) const;
    size_t getNumberOfNode(void) const;
};
 
//
// 创建二叉树.
// 这里基于前序遍历构造二叉树,输入的是二叉树的先序序列,
// 但必须在其中加入虚节点以表示空指针的位置.
// 例如:
//             (A)
//           /    \
//        (B)     (C)
//       /   \   /   \
//     (D)   %  (E)  (F)
//    /  \     /  \  / \
//   %   %    %   % %   %
//
// 其中字母代表节点,% 代表虚节点,故上图先序序列为:ABD%%%CE%%F%%.
//
// 参数 ppRoot 是指向根指针的指针,故修改 *ppRoot 就修改了实参(根指针)本身.
// 参数 ppArray 是指向存储先序序列数组地址的指针,我们也需要必要的修改.
// 参数 piSize 是指向表示数组大小的整型变量的指针,我们也需要修改它.
// 参数 delim 是分隔符,用来指代虚节点,我们需要跳过虚节点。
//
template <typename T>
void BinaryTree<T>::_create(Node<T> **ppRoot,
                            T **ppArray,
                            int *piSize,
                            const T &delim)
{
    if (0 < *piSize && delim != **ppArray)
    {
        *ppRoot = new Node<T>(**ppArray);
        _create(&((*ppRoot)->_pLeftChild), &(++*ppArray), &(--*piSize), delim);
        _create(&((*ppRoot)->_pRightChild), &(++*ppArray), &(--*piSize), delim);
    }
}
//
// 删除所有节点.
//
template <typename T>
void BinaryTree<T>::_clear(Node<T> *pRoot)
{
    if (NULL != pRoot)
    {
        _clear(pRoot->_pLeftChild);
        _clear(pRoot->_pRightChild);
        delete pRoot;
    }
}
 
//
// 前序遍历.
//
template <typename T>
void BinaryTree<T>::_preOrder(Node<T> *pRoot) const
{
    if (NULL != pRoot)
    {
        std::cout << pRoot->_data << " ";
        _preOrder(pRoot->_pLeftChild);
        _preOrder(pRoot->_pRightChild);
    }
}
 
//
// 中序遍历.
//
template <typename T>
void BinaryTree<T>::_inOrder(Node<T> *pRoot) const
{
    if (NULL != pRoot)
    {
        _inOrder(pRoot->_pLeftChild);
        std::cout << pRoot->_data << " ";
        _inOrder(pRoot->_pRightChild);
    }
}
 
//
// 后序遍历.
//
template <typename T>
void BinaryTree<T>::_postOrder(Node<T> *pRoot) const
{
    if (NULL != pRoot)
    {
        _postOrder(pRoot->_pLeftChild);
        _postOrder(pRoot->_pRightChild);
        std::cout << pRoot->_data << " ";
    }
}
 
//
// 通过后序遍历方式计算二叉树高度.
//
template <typename T>
size_t BinaryTree<T>::_height(Node<T> *pRoot) const
{
    static size_t height = 0, leftHeight = 0, rightHeight = 0;
     
    if (NULL != pRoot)
    {
        leftHeight = _height(pRoot->_pLeftChild);
        rightHeight = _height(pRoot->_pRightChild);
         
        height = (leftHeight > rightHeight ? leftHeight : rightHeight) + 1;
    }
    else {
        height = 0;
    }
     
    return height;
}
 
//
// 通过前序遍历方式计算二叉树节点数.
//
template <typename T>
size_t BinaryTree<T>::_count(Node<T> *pRoot) const
{
    static size_t counter = 0;
     
    if (NULL != pRoot) {
        counter = _count(pRoot->_pLeftChild) + _count(pRoot->_pRightChild) + 1;
    }
    else {
        counter = 0;
    }
    return counter;
}
 
 
template <typename T>
inline BinaryTree<T>::BinaryTree(T *array, int size, const T &delim)
{
    _create(&_pRoot, &array, &size, delim);
}
 
 
template <typename T>
inline BinaryTree<T>::~BinaryTree(void)
{
    _clear(_pRoot);
}
 
//
// 根据控制标识选择遍历方式.
//
template <typename T>
void BinaryTree<T>::traversal(const TraversalType type) const
{
    switch (type)
    {
        case PRE_ORDER  :   _preOrder(_pRoot);  break;
        case IN_ORDER   :   _inOrder(_pRoot);   break
        case POST_ORDER :   _postOrder(_pRoot); break;
    }
}
 
 
template <typename T>
size_t BinaryTree<T>::getHeight(void) const
{
    return _height(_pRoot);
}
 
 
template <typename T>
size_t BinaryTree<T>::getNumberOfNode(void) const
{
    return _count(_pRoot);
}
 
//
// 测试二叉树.
//
int main(void)
{
    const size_t MAX_SIZE = 100;
    char szPreOrder[MAX_SIZE] = {'\0'};
     
    std::cout << "请输入二叉树节点数据前序序列:" << std::endl;
    while (!std::cin.getline(szPreOrder, MAX_SIZE))
    {
        std::cout << "输入错误. " << std::endl;
        std::cout << "重新输入: ";
        std::cin.clear();
        std::cin.sync();   
    }
     
    BinaryTree<char> binTree(szPreOrder, strlen(szPreOrder), ' ');
     
    //
    // 遍历二叉树.
    //
    std::cout << "前序遍历:";
    binTree.traversal(BinaryTree<char>::PRE_ORDER);
    std::cout << std::endl << "中序遍历:";
    binTree.traversal(BinaryTree<char>::IN_ORDER);
    std::cout << std::endl << "中序遍历:";
    binTree.traversal(BinaryTree<char>::POST_ORDER);
    std::cout << std::endl;
     
    std::cout << "树高:" << binTree.getHeight() << std::endl;
    std::cout << "节点:" << binTree.getNumberOfNode() << std::endl;
     
    return EXIT_SUCCESS;
}
posted @   Atypiape  阅读(2451)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示