#pragma once
#include <iostream>
#include <string>
using namespace std;
enum NodeFlag { LINK, THREAD };
template <
typename T>
struct BinaryTreeNodeThd
{
BinaryTreeNodeThd(
const T& data)
: _data(data)
, _parents(NULL)
, _pLeftChild(NULL)
, _LeftFlag(LINK)
, _pRightChild(NULL)
, _RightFlag(LINK)
{}
T _data;
BinaryTreeNodeThd<T>* _parents;
BinaryTreeNodeThd<T>* _pLeftChild;
NodeFlag _LeftFlag;
BinaryTreeNodeThd<T>* _pRightChild;
NodeFlag _RightFlag;
};
template <
typename T>
class BinaryTreeThd
{
typedef BinaryTreeNodeThd<T> Node;
protected:
Node* _pRoot;
public:
BinaryTreeThd()
{}
BinaryTreeThd(
const T* arr, size_t size,
const T& invalid)
{
size_t index =
0;
_CreateTree(_pRoot, arr, size, index, invalid);
}
void PreThread()
{
Node* pPre = NULL;
_PreThread(_pRoot, pPre);
cout <<
"BinaryTree PreThread done" << endl << endl;
}
void PreOrderThd()
{
cout <<
"BinaryThreadTree PreOrder: ";
Node* pCur = _pRoot;
while (pCur)
{
while (pCur && pCur->_LeftFlag == LINK)
{
cout << pCur->_data <<
" ";
pCur = pCur->_pLeftChild;
}
cout << pCur->_data <<
" ";
pCur = pCur->_pRightChild;
}
cout << endl << endl;
}
void InThread()
{
Node* pPre = NULL;
_InThread(_pRoot, pPre);
cout <<
"BinaryTree InThread done" << endl << endl;
}
void InOrderThd()
{
if (NULL == _pRoot)
return;
cout <<
"BinaryThreadTree InOrder: ";
Node* pCur = _pRoot;
while (pCur)
{
while (LINK == pCur->_LeftFlag)
pCur = pCur->_pLeftChild;
cout << pCur->_data <<
" ";
while (pCur->_RightFlag == THREAD)
{
pCur = pCur->_pRightChild;
cout << pCur->_data <<
" ";
}
pCur = pCur->_pRightChild;
}
cout << endl << endl;
}
void PostThread()
{
Node* pPre = NULL;
_PostThread(_pRoot, pPre);
cout <<
"BinaryTree PostThread done" << endl << endl;
}
void PostOrderThd()
{
cout <<
"BinaryThreadTree PostOrder: ";
if (NULL == _pRoot)
return;
Node* pCur = _pRoot;
Node* pPre = NULL;
while (pCur)
{
while (pPre != pCur->_pLeftChild && LINK == pCur->_LeftFlag)
pCur = pCur->_pLeftChild;
while (pCur && THREAD == pCur->_RightFlag)
{
cout << pCur->_data <<
" ";
pPre = pCur;
pCur = pCur->_pRightChild;
}
if (pCur == _pRoot)
{
cout << pCur->_data <<
" " << endl << endl;
return;
}
while(pCur && pPre == pCur->_pRightChild)
{
cout << pCur->_data <<
" ";
pPre = pCur;
pCur = pCur->_parents;
}
if (pCur && LINK == pCur->_RightFlag)
pCur = pCur->_pRightChild;
}
cout << endl << endl;
}
private:
void _CreateTree(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]);
_CreateTree(pRoot->_pLeftChild, arr, size, ++index, invalid);
if (pRoot->_pLeftChild)
pRoot->_pLeftChild->_parents = pRoot;
_CreateTree(pRoot->_pRightChild, arr, size, ++index, invalid);
if (pRoot->_pRightChild)
pRoot->_pRightChild->_parents = pRoot;
}
}
void _PreThread(Node*& pRoot, Node*& pPre)
{
if (NULL == pRoot)
return;
if (NULL == pRoot->_pLeftChild)
{
pRoot->_pLeftChild = pPre;
pRoot->_LeftFlag = THREAD;
}
if (pPre && NULL == pPre->_pRightChild)
{
pPre->_pRightChild = pRoot;
pPre->_RightFlag = THREAD;
}
pPre = pRoot;
if (pRoot->_LeftFlag == LINK)
_PreThread(pRoot->_pLeftChild, pPre);
if(pRoot->_RightFlag == LINK)
_PreThread(pRoot->_pRightChild, pPre);
}
void _InThread(Node*& pRoot, Node*& pPre)
{
if (NULL == pRoot)
return;
if (pRoot->_LeftFlag == LINK)
_InThread(pRoot->_pLeftChild, pPre);
if (NULL == pRoot->_pLeftChild)
{
pRoot->_pLeftChild = pPre;
pRoot->_LeftFlag = THREAD;
}
if (pPre && NULL == pPre->_pRightChild)
{
pPre->_pRightChild = pRoot;
pPre->_RightFlag = THREAD;
}
pPre = pRoot;
if (pRoot->_RightFlag == LINK)
_InThread(pRoot->_pRightChild, pPre);
}
void _PostThread(Node*& pRoot, Node*& pPre)
{
if (NULL == pRoot)
return;
if (pRoot->_LeftFlag == LINK)
_PostThread(pRoot->_pLeftChild, pPre);
if (pRoot->_RightFlag == LINK)
_PostThread(pRoot->_pRightChild, pPre);
if (NULL == pRoot->_pLeftChild)
{
pRoot->_pLeftChild = pPre;
pRoot->_LeftFlag = THREAD;
}
if (pPre && NULL == pPre->_pRightChild)
{
pPre->_pRightChild = pRoot;
pPre->_RightFlag = THREAD;
}
pPre = pRoot;
}
};
void FunTest()
{
char* arr =
"12#3##45#6#7##8";
BinaryTreeThd<
char> bt(arr,
strlen(arr),
'#');
BinaryTreeThd<
char> bt1(arr,
strlen(arr),
'#');
BinaryTreeThd<
char> bt2(arr,
strlen(arr),
'#');
bt.PreThread();
bt.PreOrderThd();
bt1.InThread();
bt1.InOrderThd();
bt2.PostThread();
bt2.PostOrderThd();
}