zoukankan      html  css  js  c++  java
  • 简单链式二叉树(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;
    }
    
  • 相关阅读:
    I/O性能优化
    磁盘性能指标
    磁盘I/O工作原理
    文件系统工作原理
    Linux命令行工具之free命令
    内存性能优化
    内存工作原理
    内存中的Buffer和Cache的区别
    proc文件系统
    oracle 查询 LOB 字段大小
  • 原文地址:https://www.cnblogs.com/wxxweb/p/2060118.html
Copyright © 2011-2022 走看看