.hpp
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>
#include<queue>
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& data)
:_left(NULL)
, _right(NULL)
, _data(data)
{}
BinaryTreeNode* _left;//左指针域
BinaryTreeNode* _right;//右指针域
T _data;//数据域
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_pRoot(NULL)
{}
//构造
BinaryTree(T* arr, size_t size)
{
assert(arr);
size_t index = 0;
_CreateBinaryTree(_pRoot,arr,size,index);
}
//拷贝构造
BinaryTree(const BinaryTree<T>& bt)
{
_pRoot=_CopyBinaryTree(bt._pRoot);
}
//赋值操作符重载
BinaryTree& operator =(const BinaryTree<T>& bt)
{
if (this != &bt)
{
_DestroyTree(_pRoot);
_CopyBinaryTree(bt._pRoot);
}
return *this;
}
//简洁版的写法
BinaryTree& operator =(BinaryTree<T> bt)
{
std::swap(_pRoot, bt._pRoot);//缺点是不能避免自己跟自己赋值
return *this;
}
//析构函数
~BinaryTree()
{
if (_pRoot)
{
_DestroyTree(_pRoot);
_pRoot = NULL;
}
}
public:
//前序遍历(递归)
void PrevOrder()
{
cout << "前序遍历" << ": ";
_PrevOrder(_pRoot);
cout << endl;
}
//中序遍历(递归)
void InOrder()
{
cout << "中序遍历" << ": ";
_InOrder(_pRoot);
cout << endl;
}
//后序遍历(递归)
void PostOrder()
{
cout << "后序遍历" << " ";
_PostOrder(_pRoot);
cout << endl;
}
//层序遍历
void LevelOrder()
{
_LevelOrder(_pRoot);
}
//求树的深度
void Height()
{
cout << "树的深度" << " : ";
cout << _Height(_pRoot) << endl;;
}
//求叶子节点的个数
void GetLeefCount()
{
cout << "叶子结点的个数:";
cout << _GetLeefCount(_pRoot) << endl;
}
//求第K层结点的个数
void GetKLevelNodeCount(size_t k)
{
cout << "第k层结点的个数:"<<" ";
if (k > _Height(_pRoot))
{
cout << "0" << endl;
return;
}
cout << _GetKLevelNodeCount(_pRoot, k) << endl;
}
// 值为data的结点是否存在
Node* Find(const T& data)
{
return _Find(_pRoot, data);
}
//求pNode的双亲
Node* GetParent(Node* pNode)
{
return _GetParent(_pRoot, pNode);
}
//求一棵树一共有多少结点
void GetTreeNodeCount()
{
cout << "树的总结点数:" << " ";
cout << _GetTreeNodeCount(_pRoot) << endl;
}
//判断一个结点在不在树中
bool IsNodeInTree(Node* pNode)
{
return _IsNodeInTree(_pRoot, pNode);
}
// 获取二叉树的左孩子
Node* GetLeftChild(Node* pCur)
{
return pCur->_left;
}
// 获取二叉树的右孩子
Node* GetRightChild(Node* pCur)
{
return pCur->_right;
}
protected:
//构造的实现
void _CreateBinaryTree(Node*& pRoot, T* arr, size_t size, size_t& index)
{
if ((index < size) && ('#' != arr[index]))
{
pRoot = new Node(arr[index]);
_CreateBinaryTree(pRoot->_left, arr, size, ++index);
_CreateBinaryTree(pRoot->_right, arr, size, ++index);
}
}
//拷贝构造实现
Node* _CopyBinaryTree(Node* pRoot)
{
if (NULL == pRoot)
return NULL;
Node* _pRoot = new Node(pRoot->_data);
_pRoot->_left = _CopyBinaryTree(pRoot->_left);
_pRoot->_right = _CopyBinaryTree(pRoot->_right);
return _pRoot;
}
//销毁函数
void _DestroyTree(Node*& pRoot)
{
if (NULL == pRoot)//如果根结点为空,不需要释放,直接返回
return;
_DestroyTree(pRoot->_left);
_DestroyTree(pRoot->_right);
delete pRoot;
pRoot = NULL;
}
//前序遍历(递归)实现方法
void _PrevOrder(Node*& pRoot)
{
if (NULL == pRoot)
return;
cout << pRoot->_data << " ";
_PrevOrder(pRoot->_left);
_PrevOrder(pRoot->_right);
}
//前序遍历(循环)实现方法
void _PrevOrder(Node*& pRoot)
{
stack<Node*> s1;
if (pRoot)
s1.push(pRoot);
while (!s1.empty())
{
Node* cur = s1.top();
s1.pop();
if (cur->_right)
s1.push(cur->_right);
if (cur->_left)
s1.push(cur->_left);
cout << cur->_data << " ";
}
}
//中序遍历(递归)实现方法
void _InOrder(Node*& pRoot)
{
if (NULL == pRoot)
return;
_InOrder(pRoot->_left);
cout << pRoot->_data << " ";
_InOrder(pRoot->_right);
}
//中序遍历(循环)实现方法
void _InOrder(Node*& pRoot)
{
stack<Node*> s;
Node* cur = pRoot;
while (NULL != cur || !s.empty())//判断条件是关键点
{
while (NULL != cur)
{
s.push(cur);
cur = cur->_left;
}
Node* node = s.top();
s.pop();
cout << node->_data << " ";
cur = node->_right;
}
}
//后续遍历(递归)实现方法
void _PostOrder(Node*& pRoot)
{
if (NULL == pRoot)
return;
_PostOrder(pRoot->_left);
_PostOrder(pRoot->_right);
cout << pRoot->_data << " ";
}
//后续遍历(循环)实现方法
void _PostOrder(Node*& pRoot)
{
stack<Node*> s1;
stack<Node*> s2;
if (pRoot)
s1.push(pRoot);
Node* prev = NULL;
while (!s1.empty())
{
Node* cur = s1.top();
while (!s1.empty())
{
Node* cur = s1.top();
s1.pop();
s2.push(cur);
if (cur->_left)
s1.push(cur->_left);
if (cur->_right)
s1.push(cur->_right);
}
while (!s2.empty())
{
Node* tmp = s2.top();
cout << tmp->_data << " ";
s2.pop();
}
}
}
//层序遍历树
void _LevelOrder(Node*& pRoot)
{
queue<Node*> q;
if (NULL != pRoot)
q.push(pRoot);
while (NULL != pRoot)
{
pRoot = q.front();
if (NULL != pRoot->_left)
q.push(pRoot->_left);
if (NULL != pRoot->_right)
q.push(pRoot->_right);
cout <<q.front()->_data<< " ";
q.pop();
if (q.empty())
pRoot = NULL;
}
cout << endl;
}
//求高度实现实现方法
size_t _Height(Node*& pRoot)
{
if (NULL == pRoot)
return 0;
return (((_Height(pRoot->_left))>(_Height(pRoot->_right))) ? (_Height(pRoot->_left) + 1):(_Height(pRoot->_right)+1));
}
//求也只结点的个数
size_t _GetLeefCount(Node*& pRoot)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_left && NULL == pRoot->_right)
return 1;
return (_GetLeefCount(pRoot->_left) + _GetLeefCount(pRoot->_right));
}
//求第K层结点的个数
size_t _GetKLevelNodeCount(Node*& pRoot,size_t k)
{
if (NULL == pRoot || k < 1)
return 0;
if (1 == k)
return 1;
//可以划分成K-1层,左 + 右孩子的个数
size_t Leftcount = _GetKLevelNodeCount(pRoot->_left, k - 1);
size_t Rightcount = _GetKLevelNodeCount(pRoot->_right, k - 1);
return Leftcount + Rightcount;
}
//查找一个值为data的元素是不是在树里面
Node* _Find(Node* pRoot, const T& data)
{
if (NULL == pRoot)
return NULL;
if (pRoot->_data == data)
return pRoot;
Node* cur = _Find(pRoot->_left, data);
if (cur)
return cur;
return _Find(pRoot->_right, data);
}
//求pNode的双亲
Node* _GetParent(Node* pRoot, Node* pNode)
{
if (NULL == pRoot || NULL == pNode)
return NULL;
if (pRoot->_left == pNode || pRoot->_right == pNode)
return pRoot;
Node* cur = _GetParent(pRoot->_left, pNode);
if (cur)
return cur;
return _GetParent(pRoot->_right, pNode);
}
//求二叉树中总结点的个数
size_t _GetTreeNodeCount(Node* pRoot)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_left && NULL == pRoot->_right)
return 1;
return _GetTreeNodeCount(pRoot->_left) + _GetTreeNodeCount(pRoot->_right)+1;
}
//判断一个结点在不在树中
bool _IsNodeInTree(Node*& pRoot,Node* pNode)
{
if (NULL == pRoot || NULL == pNode)
return false;
if (pNode == pRoot)
return true;
bool cur = _IsNodeInTree(pRoot->_left, pNode);
if (cur)
return true;
return _IsNodeInTree(pRoot->_right, pNode);
}
protected:
Node* _pRoot;
};