现在的位置: 首页 > 综合 > 正文

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

2012年12月04日 ⁄ 综合 ⁄ 共 4079字 ⁄ 字号 评论关闭

下面代码仅供本人复习数据结构所用,实用性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;
}
【上篇】
【下篇】

抱歉!评论已关闭.