线索化二叉树:
当某个节点的左孩子为空时,将_pLeft指针指向他的前一个节点;
当某个节点的右孩子为空时,将_pRight指针指向它的后一个结点。
根据遍历方式不同,得到的前后节点也不同,线索化二叉树分为三种不同的情况:
先序遍历线索化二叉树
中序遍历线索化二叉树
后序遍历线索化二叉树
线索二叉树与普通二叉树有什么区别呢?线索化二叉树中空的指针域至多2个,至少1个;
普通二叉树中空的指针域是n+1个,n(节点数)。
所以能够有效地利用资源,并且在遍历时不用递归和栈结构也可以遍历。
为了区别两个节点的关系是双亲-孩子节点,还是前驱-后继节点,可以在每个节点创建时 ,增加两个成员变量,_leftThread和_rightThread,这两个变量只有两种状态,LINK(双亲-孩子)、THREAD(前驱=后继)。
#include
#include
#include
using namespace std;
enum PointIhfo
{
LINK,
THREAD
};
template <class T>
struct BinaryTreeNodeThd//定义二叉树的节点
{
BinaryTreeNodeThd(const T& value)
:_value(value)
,_pLeft(NULL)
,_pRight(NULL)
,_pParent(NULL)
, _leftThread(LINK)
, _rightTrhead(LINK)
{}
T _value;
BinaryTreeNodeThd* _pLeft;
BinaryTreeNodeThd* _pRight;
BinaryTreeNodeThd* _pParent;
PointIhfo _leftThread;
PointIhfo _rightTrhead;
};
template
class BinaryTreeThd
{
typedef BinaryTreeNodeThd Node;
public:
BinaryTreeThd()
:_pRoot(NULL)
{}
BinaryTreeThd(const T arr[], size_t size, const T& invalid)
{
size_t index=0;
_CreateBinaryTree(_pRoot, NULL, arr, size, index, invalid);
}
BinaryTreeThd(const BinaryTreeThd& bt)
{
_pRoot = _CopyBinaryTree(bt._pRoot);
}
BinaryTreeThd& operator=(const BinaryTreeThd& bt)
{
if(this != &bt)
{
_DestroyBinaryTree(_pRoot);
_pRoot = _CopyBinaryTree(bt._pRoot);
}
return *this;
}
~BinaryTreeThd()
{
_DestroyBinaryTree(_pRoot);
}
void PreThread()
{
Node* prev = NULL;
_PreThread(_pRoot, prev);
}
void InThread()
{
Node* prev = NULL;
_InThread(_pRoot, prev);
}
void PostThread()
{
Node* prev = NULL;
_PostThread(_pRoot, prev);
}
void PreOrder()
{
if(_pRoot == NULL)
return;
Node* pCur = _pRoot;
while(pCur)
{
while(pCur->_leftThread == LINK)//访问到最左结点
{
cout<_value<<" ";
pCur = pCur->_pLeft;
}
cout<_value<<" ";//访问最左边的节点
while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问
{
pCur = pCur->_pRight;
cout<_value<<" ";
}
if(pCur->_leftThread == LINK)//如果该结点有左孩子,则访问左孩子
pCur = pCur->_pLeft;
else //否则访问右孩子
pCur = pCur->_pRight;
}
}
void InOrder()
{
if(_pRoot == NULL)
return;
Node* pCur = _pRoot;
while(pCur)
{
while(pCur->_leftThread == LINK)//找最左节点
pCur = pCur->_pLeft;
cout<_value<<" ";//访问最左结点
while(pCur->_rightTrhead == THREAD)//如果该结点没有右孩子,则一直访问该节点
{
pCur = pCur->_pRight;
cout<_value<<" ";
}
pCur = pCur->_pRight;//如果该结点有右孩子,则访问右孩子
}
}
void PostOrder()
{
if(_pRoot == NULL)
return;
Node* pCur = _pRoot;
Node* pPre = NULL;
while(pCur)
{
while(pCur->_leftThread == LINK)//找到最左结点
pCur = pCur->_pLeft;
while(pCur && pCur->_rightTrhead == THREAD)//如果最左结点存在且它的右孩子
{ //不存在,就一直访问它的右孩子
cout<_value<<" ";
pPre = pCur; //将当前节点保存
pCur = pCur->_pRight;
}
while(pCur && pCur->_pRight == pPre) //如果当前节点的右孩子刚刚被访问,就访问当前节点
{
cout<_value<<" ";
pPre = pCur;
pCur = pCur->_pParent;
}
if(pCur && pCur->_rightTrhead == LINK)//如果当前节点的右孩子存在,就访问它的右孩子
pCur = pCur->_pRight;
}
}
private:
void _CreateBinaryTree(Node* &pRoot, Node* pParent, const T arr[], size_t size, size_t& index, const T& invalid)
{
if(index//创建根节点
pRoot = new Node(arr[index]);
pRoot->_pParent = pParent;
//创建左子树
_CreateBinaryTree(pRoot->_pLeft, pRoot, arr, size, ++index, invalid);
pRoot->_leftThread = LINK;
//创建右子树
_CreateBinaryTree(pRoot->_pRight, pRoot, arr, size, ++index, invalid);
pRoot->_rightTrhead = LINK;
}
}
Node* _CopyBinaryTree(Node* pRoot)
{
Node* pNode = NULL;
if(pRoot)
{
pNode = new Node(pRoot->_value);
pNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);
pNode->_leftThread = pRoot->_leftThread;
pNode->_pParent = pRoot->_pParent;
pNode->_pRight = _CopyBinaryTree(pRoot->_pRight);
pNode->_rightTrhead = pRoot->_rightTrhead;
pNode->_pParent = pRoot->_pParent;
}
return pNode;
}
void _DestroyBinaryTree(Node*& pRoot)
{
if(pRoot)
{
_DestroyBinaryTree(pRoot->_pLeft);
_DestroyBinaryTree(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
}
void _PreThread(Node* pRoot, Node*& prev)
{
if(pRoot == NULL)
return;
if(pRoot->_pLeft == NULL)
{
pRoot->_pLeft = prev;
pRoot->_leftThread = THREAD;
}
if(prev && prev->_pRight == NULL)
{
prev->_pRight = pRoot;
prev->_rightTrhead = THREAD;
}
prev = pRoot;
if(pRoot->_leftThread == LINK)
_PreThread(pRoot->_pLeft, prev);
if(pRoot->_rightTrhead == LINK)
_PreThread(pRoot->_pRight, prev);
}
void _InThread(Node* pRoot, Node*& prev)
{
if(pRoot == NULL)
return;
//左子树
if(pRoot->_leftThread == LINK)
_InThread(pRoot->_pLeft, prev);
if(pRoot->_pLeft == NULL)
{
pRoot->_pLeft = prev;
pRoot->_leftThread = THREAD;
}
if(prev && prev->_pRight == NULL)
{
prev->_pRight = pRoot;
prev->_rightTrhead = THREAD;
}
prev = pRoot;
//右子树
if(pRoot->_rightTrhead == LINK)
_InThread(pRoot->_pRight, prev);
}
void _PostThread(Node* pRoot, Node*& prev)
{
if(pRoot == NULL)
return;
//左子树
if(pRoot->_leftThread == LINK)
_PostThread(pRoot->_pLeft, prev);
//右子树
if(pRoot->_rightTrhead == LINK)
_PostThread(pRoot->_pRight, prev);
if(pRoot->_pLeft == NULL)
{
pRoot->_pLeft = prev;
pRoot->_leftThread = THREAD;
}
if(prev && prev->_pRight == NULL)
{
prev->_pRight = pRoot;
prev->_rightTrhead = THREAD;
}
prev = pRoot;
}
private:
Node* _pRoot;//根节点
};
int main()
{
char* arr = "124##5##3#6";
BinaryTreeThd<char> bt1(arr, strlen(arr), '#');
//bt1.PreThread();
//bt1.PreOrder();
//bt1.InThread();
//bt1.InOrder();
bt1.PostThread();
bt1.PostOrder();
//BinaryTreeThd bt2(bt1);
system("pause");
return 0;
}