#pragma once
#include<iostream>
#include<windows.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& value)
: _value(value)
, _pLeft(NULL)
, _pRight(NULL)
{}
T _value;
BinaryTreeNode<T>* _pLeft;
BinaryTreeNode<T>* _pRight;
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
: _pRoot(NULL)
{}
BinaryTree(const T arr[], size_t size, const T& invalid)
{
size_t index = 0;
_CreateBinaryTree(_pRoot, arr, size, index, invalid);
}
BinaryTree(const BinaryTree<T>& bt)
{
_pRoot = _CopyBirnaryTree(bt._pRoot);
}
BinaryTree<T>& operator=(const BinaryTree<T>& bt)
{
if (this != &bt)
{
_DestroyBinaryTree(_pRoot);
_pRoot=_CopyBirnaryTree(bt._pRoot);
}
return *this;
}
~BinaryTree()
{
_DestroyBinaryTree(_pRoot);
}
void PreOrder()
{
cout << "PreOrder:" << endl;
_PreOrder(_pRoot);
cout << endl;
}
void PreOrder_Nor()
{
cout << "PreOrder_Nor:" << endl;
_PreOrder_Nor(_pRoot);
cout << endl;
}
void InOrder()
{
cout << "InOrder:" << endl;
_InOrder(_pRoot);
cout << endl;
}
void InOrder_Nor()
{
cout << "InOrder_Nor:" << endl;
_InOrder_Nor(_pRoot);
cout << endl;
}
void PostOrder()
{
cout << "PostOrder:" << endl;
_PostOrder(_pRoot);
cout << endl;
}
void PostOrder_Nor()
{
cout << "PostOrder_Nor:" << endl;
_PostOrder_Nor(_pRoot);
cout << endl;
}
void LevelOrder()
{
cout << "LevelOrde:" << endl;
_LevelOrder(_pRoot);
cout << endl;
}
Node* Find(const T& value)
{
return _Find(_pRoot, value);
}
void FindPath(size_t WantSum)
{
size_t Cursum = 0;
vector<int>path;
_FindPath(_pRoot, WantSum, path, Cursum);
}
Node* Parent(Node* pCur)
{
return _Parent(_pRoot, pCur);
}
Node* GetLeftChild(Node* pCur)
{
return (pCur == NULL) ? NULL : pCur->_pLeft;
}
Node* GetRightChild(Node* pCur)
{
return (pCur == NULL) ? NULL : pCur->_pRight;
}
size_t Height()
{
return _Height(_pRoot);
}
size_t GetLeefCount()
{
return _GetLeefCount(_pRoot);
}
size_t GetKLevelCount(size_t k)
{
return _GetKLevelCount(_pRoot, k);
}
void BinaryMirror_Nor()
{
return _BinaryMirror_Nor();
}
void BinaryMirror()
{
return _BinaryMirror(_pRoot);
}
private:
void _CreateBinaryTree(Node* &pRoot, const T arr[], size_t size, size_t& index, const T& invalid)
{
if (index < size&&arr[index] != invalid)
{
pRoot = new Node(arr[index]);
_CreateBinaryTree(pRoot->_pLeft, arr, size, ++index, invalid);
_CreateBinaryTree(pRoot->_pRight, arr, size, ++index, invalid);
}
}
Node* _CopyBirnaryTree(Node* pRoot)
{
Node* pNewRoot = NULL;
if (pRoot)
{
pNewRoot = new Node(pRoot[0]);
pNewRoot->_pLeft = _CopyBirnaryTree(pRoot->_pLeft);
pNewRoot->_pRight = _CopyBirnaryTree(pRoot->_pRight);
}
return pNewRoot;
}
void _DestroyBinaryTree(Node*& pRoot)
{
if (pRoot)
{
_DestroyBinaryTree(pRoot->_pLeft);
_DestroyBinaryTree(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
}
void _PreOrder(Node* pRoot)
{
if (pRoot)
{
cout << pRoot->_value << " ";
_PreOrder(pRoot->_pLeft);
_PreOrder(pRoot->_pRight);
}
}
void _PreOrder_Nor(Node*pRoot)
{
if (NULL == pRoot)
return;
stack<Node*>s;
s.push(pRoot);
while (!s.empty())
{
Node*pCur = s.top();
cout << pCur->_value << " ";
s.pop();
if (pCur->_pRight)
s.push(pCur->_pRight);
if (pCur->_pLeft)
s.push(pCur->_pLeft);
}
}
void _InOrder(Node* pRoot)
{
if (pRoot)
{
_InOrder(pRoot->_pLeft);
cout << pRoot->_value << " ";
_InOrder(pRoot->_pRight);
}
}
void _InOrder_Nor(Node*pRoot)
{
if (NULL == pRoot)
return;
stack<Node*>s;
Node*pCur = pRoot;
while (pCur || !s.empty())
{
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeft;
}
pCur = s.top();
cout << pCur->_value << " ";
s.pop();
pCur = pCur->_pRight;
}
}
void _PostOrder(Node* pRoot)
{
if (pRoot)
{
_PostOrder(pRoot->_pLeft);
_PostOrder(pRoot->_pRight);
cout << pRoot->_value << " ";
}
}
void _PostOrder_Nor(Node*pRoot)
{
if (NULL == pRoot)
return;
stack<Node*>s;
Node*pCur = pRoot;
Node*Prev = NULL;
while (pCur || !s.empty())
{
while (pCur)
{
s.push(pCur);
pCur = pCur->_pLeft;
}
Node*pTop = s.top();
if (NULL == pTop->_pRight || Prev == pTop->_pRight)
{
cout << pTop->_value << " ";
Prev = pTop;
s.pop();
}
else
{
pCur = pTop;
pCur = pCur->_pRight;
}
}
}
void _LevelOrder(Node*pRoot)
{
if (NULL == pRoot)
return;
queue<Node*>q;
q.push(pRoot);
while (!q.empty())
{
Node*pcur = q.front();
cout << pcur->_value << " ";
if (pcur->_pLeft)
{
q.push(pcur->_pLeft);
}
if (pcur->_pRight)
{
q.push(pcur->_pRight);
}
q.pop();
}
cout << endl;
}
void _FindPath(Node*pRoot, size_t WantSum, vector<int>&path, size_t CurSum)
{
CurSum += pRoot->_value;
path.push_back(pRoot->_value);
if (CurSum == WantSum&&NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
{
cout << WantSum << "path is found:" << endl;
vector<int>::iterator it = path.begin();
while (!path.empty() && it != path.end())
{
cout << *it << " ";
it++;
}
cout << endl;
}
if (pRoot->_pLeft)
{
_FindPath(pRoot->_pLeft, WantSum, path, CurSum);
}
if (pRoot->_pRight)
{
_FindPath(pRoot->_pRight, WantSum, path, CurSum);
}
path.pop_back();
}
Node* _Find(Node* pRoot, const T& value)
{
Node*pCur = NULL;
if (NULL == pRoot)
return NULL;
if (pRoot->_value == value)
{
return pRoot;
}
pCur = _Find(pRoot->_pLeft, value);
if (NULL!=pCur)
return pCur;
return _Find(pRoot->_pRight, value);
}
Node* _Parent(Node* pRoot, Node* pCur)
{
if (NULL == pRoot)
return NULL;
if (NULL==pRoot->_pLeft&&NULL == pRoot->_pRight)
return NULL;
if (pRoot == pCur)
return NULL;
if (pCur == pRoot->_pLeft || pCur == pRoot->_pRight)
return pRoot;
Node*parent = NULL;
parent = _Parent(pRoot->_pLeft, pCur);
if (NULL != pCur)
return pCur;
return _Parent(pRoot->_pLeft, pCur);
}
size_t _Height(Node* pRoot)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
return 1;
size_t Left_Height=_Height(pRoot->_pLeft);
size_t Right_Height = _Height(pRoot->_pRight);
return Left_Height > Right_Height ? Left_Height + 1 : Right_Height + 1;
}
size_t _GetLeefCount(Node* pRoot)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_pLeft&&NULL == pRoot->_pRight)
return 1;
size_t Left_LeefCount=_GetLeefCount(pRoot->_pLeft);
size_t Right_LeefCount = _GetLeefCount(pRoot->_pRight);
return Left_LeefCount + Right_LeefCount;
}
size_t _GetKLevelCount(Node* pRoot, size_t k)
{
if (NULL == pRoot || k<1)
return 0;
if (k == 1)
return 1;
size_t LeftKLevelCount=_GetKLevelCount(pRoot->_pLeft, k - 1);
size_t RighttKLevelCount = _GetKLevelCount(pRoot->_pRight, k - 1);
return LeftKLevelCount + RighttKLevelCount;
}
void _BinaryMirror(Node* pRoot)
{
if (NULL == pRoot)
return;
swap(pRoot->_pLeft, pRoot->_pRight);
_BinaryMirror(pRoot->_pLeft);
_BinaryMirror(pRoot->_pRight);
}
void _BinaryMirror_Nor()
{
if (NULL == _pRoot)
return;
queue<Node*>q;
q.push(_pRoot);
while (!q.empty())
{
Node*pCur = q.front();
if (pCur)
{
q.push(pCur->_pLeft);
}
if (pCur)
{
q.push(pCur->_pRight);
}
if (NULL!=pCur)
swap(pCur->_pLeft, pCur->_pRight);
q.pop();
}
}
private:
Node* _pRoot;
};