二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。
#include <iostream>
using namespace std;
enum PointerTag {THREAD, LINK};
template<class T>
struct BinaryTreeNodeThd
{
T _data; //数据
BinaryTreeNodeThd<T>* _left; //左孩子
BinaryTreeNodeThd<T>* _right; //右孩子
PointerTag _leftTag; //左孩子线索标志
PointerTag _rightTag; //右孩子线索标志
BinaryTreeNodeThd(const T& data)
:_data(data)
,_left(NULL)
,_right(NULL)
,_leftTag(LINK)
,_rightTag(LINK)
{}
};
template<class T>
class BinaryTreeThd
{
public:
BinaryTreeThd(const T* array, size_t size, const T& invalid)
{
size_t index = 0;
_root = _CreateTree(array, size, index, invalid);
}
~BinaryTreeThd()
{
_DestroyTree(_root);
_root = NULL;
}
void InOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_InOrderThreading(_root, prev);
}
void PreOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_PreOrderThreading(_root, prev);
}
void PostOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_PostOrderThreading(_root, prev);
}
void PreOrderThd()
{
BinaryTreeNodeThd<T>* cur = _root;
while (cur)
{
while (cur && LINK == cur->_leftTag)
{
cout<<cur->_data<<" ";
cur = cur->_left;
}
cout<<cur->_data<<" ";
cur = cur->_right;
}
cout<<endl;
}
void InOrderThd()
{
BinaryTreeNodeThd<T>* cur = _root;
while (cur)
{
while (cur && LINK == cur->_leftTag)
{
cur = cur->_left;
}
cout<<cur->_data<<" ";
while (THREAD == cur->_rightTag)
{
cur = cur->_right;
cout<<cur->_data<<" ";
}
cur = cur->_right;
}
cout<<endl;
}
protected:
BinaryTreeNodeThd<T>* _CreateTree(const T* array, size_t size, size_t& index, const T& invalid)
{
BinaryTreeNodeThd<T>* root = NULL;
if (index < size && array[index] != invalid)
{
root = new BinaryTreeNodeThd<T>(array[index]);
root->_left = _CreateTree(array, size, ++index, invalid);
root->_right = _CreateTree(array, size, ++index, invalid);
}
return root;
}
void _DestroyTree(BinaryTreeNodeThd<T>* root)
{
if (NULL == root)
return;
if (LINK == root->_leftTag)
_DestroyTree(root->_left);
if (LINK == root->_rightTag)
_DestroyTree(root->_right);
delete root;
}
void _PreOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (NULL == cur)
return;
if (NULL == cur->_left)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev && NULL == prev->_right)
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;
if (cur->_leftTag == LINK)
_PreOrderThreading(cur->_left, prev);
if (cur->_rightTag == LINK)
_PreOrderThreading(cur->_right, prev);
}
void _InOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (NULL == cur)
return;
_InOrderThreading(cur->_left, prev);
if (NULL == cur->_left)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev && NULL == prev->_right)
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;
_InOrderThreading(cur->_right, prev);
}
void _PostOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (NULL == cur)
return;
_PostOrderThreading(cur->_left, prev);
_PostOrderThreading(cur->_right, prev);
if (cur->_left == NULL)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev && NULL == prev->_right)
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;
}
protected:
BinaryTreeNodeThd<T>* _root;
};
void Test()
{
int a[] = {1, 2, 3, '#', '#', 4, '#', '#', 5, 6};
BinaryTreeThd<int> t1(a, sizeof(a)/sizeof(a[0]), '#');
t1.PreOrderThreading();
t1.PreOrderThd();
BinaryTreeThd<int> t2(a, sizeof(a)/sizeof(a[0]), '#');
t2.InOrderThreading();
t2.InOrderThd();
int a1[] = {1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8};
BinaryTreeThd<int> t3(a1, sizeof(a1)/sizeof(a1[0]), '#');
t3.PreOrderThreading();
t3.PreOrderThd();
}
int main()
{
Test();
return 0;
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。