您的位置:首页 > 其它

线索化二叉树的非递归遍历(用前驱结点和后继访问)

2016-03-13 15:38 423 查看
#pragma once
#include<iostream>
using namespace std;
enum PointTag
{
THREAD,
LINK
};
template<class T>
struct BinaryTreeNodeThd
{
T _data;
BinaryTreeNodeThd<T>* _left;
BinaryTreeNodeThd<T>* _right;
BinaryTreeNodeThd<T>* _parent;
PointTag _leftTag;
PointTag _rightTag;
BinaryTreeNodeThd(const T& x)
:_data(x)
, _left(NULL)
, _right(NULL)
, _parent(NULL)
, _leftTag(LINK)
, _rightTag(LINK)
{}
};
template<class T>
class BinaryTreeThd
{
protected:
BinaryTreeNodeThd<T>* _CreateBinaryTree(T* a, size_t& index, const size_t size)
{
BinaryTreeNodeThd<T>* root = NULL;
if (index < size&&a[index] != '#')
{
root = new BinaryTreeNodeThd<T>(a[index]);
root->_left = _CreateBinaryTree(a, ++index, size);
if (root->_left)
root->_left->_parent = root;
root->_right = _CreateBinaryTree(a, ++index, size);
if (root->_right)
root->_right->_parent = root;
}
return root;
}
void _Clear(BinaryTreeNodeThd<T>* root)
{
if (root)
{
if (root->_leftTag == LINK)
_Clear(root->_left);
if (root->_rightTag == LINK)
_Clear(root->_right);
delete root;
}
}
void _InOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (cur == NULL)
return;

_InOrderThreading(cur->_left, prev);
if (cur->_left==NULL)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev&&prev->_right == NULL)
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;

_InOrderThreading(cur->_right, prev);
}

void _PreOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (cur == NULL)
return;

if (cur->_left == NULL)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev&&prev->_right == NULL)
{
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 _PostOrderThreading(BinaryTreeNodeThd<T>* cur, BinaryTreeNodeThd<T>*& prev)
{
if (cur == NULL)
return;
_PostOrderThreading(cur->_left, prev);
_PostOrderThreading(cur->_right, prev);
if (cur&&cur->_left == NULL)
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if (prev&&prev->_right == NULL)
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;
}
public:
BinaryTreeThd()
:_root(NULL)
{}
BinaryTreeThd(T* a,size_t size)
{
size_t index = 0;
_root=_CreateBinaryTree(a, index, size);
}
~BinaryTreeThd()
{
_Clear(_root);
_root = NULL;
}
void  PreOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_PreOrderThreading(_root, prev);
}
/*void PreOrderThd()
{
if (_root == NULL)
return;
BinaryTreeNodeThd<T>* cur = _root;

while (cur)
{

cout << cur->_data << " ";
while (cur&&cur->_leftTag != THREAD)
{
cur = cur->_left;
cout << cur->_data << " ";
}

while (cur&&cur->_rightTag != LINK)
{
cur = cur->_right;
cout << cur->_data << " ";
}
if (cur->_leftTag == LINK)
cur = cur->_left;
else
cur = cur->_right;
}
cout << endl;
}*/
//优化版前序遍历,发现规律,注意观察
void PreOrderThd()
{
if (_root == NULL)
return;
BinaryTreeNodeThd<T>*cur = _root;
while (cur)
{
while (cur&&cur->_leftTag == LINK)
{
cout << cur->_data << " ";
cur = cur->_left;
}
cout << cur->_data << " ";
cur = cur->_right;
}
cout << endl;
}
void  InOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_InOrderThreading(_root, prev);
}
void InOrderThd()
{
if (_root == NULL)
return;
BinaryTreeNodeThd<T>* cur = _root;
while (cur)
{
while (cur&&cur->_leftTag != THREAD)
cur = cur->_left;
cout << cur->_data << " ";
while (cur&&cur->_rightTag != LINK)
{
cur = cur->_right;
cout << cur->_data << " ";
}
cur = cur->_right;
}
cout << endl;
}
void PostOrderThreading()
{
BinaryTreeNodeThd<T>* prev = NULL;
_PostOrderThreading(_root, prev);
}
//重点
void PostOrderThd()
{
if (_root == NULL)
return;
BinaryTreeNodeThd<T>* cur = _root->_left;
BinaryTreeNodeThd<T>* prev = NULL;
int flag = 0;
while (cur != _root)
{
while (cur&&cur->_leftTag == LINK)
{
cur = cur->_left;
}
while (cur&&cur->_rightTag == THREAD)
{
cout << cur->_data << " ";
prev = cur;
cur = cur->_right;
}
if (_root == cur)
{
cout << _root->_data << " ";
prev = _root;
break;
}
while(cur&&_root!=cur&&cur->_rightTag == LINK&&cur->_right == prev)
{
cout << cur->_data << " ";
prev = cur;
cur = cur->_parent;
}
if (cur == _root)
{
if (flag == 0)
flag = 1;
else
break;
}
if (cur&&cur->_rightTag == LINK&&cur != prev)
cur = cur->_right;
else
{
cout << cur->_data << " ";
prev = cur;
cur = cur->_parent;
}

}
if(prev!=_root)
cout << _root->_data << " ";
cout << endl;
}
protected:
BinaryTreeNodeThd<T>* _root;
};
void  Test3()
{
//注意测试用例
//int array[18] = { 1, 2, 3, 7, '#','#','#',4,8,'#','#',9,'#','#',5,6,'#',10};

int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
//int array[15] = { 1, 2, '#', 3, '#', '#', 4, 5, '#', 6, '#', 7, '#', '#', 8 };
BinaryTreeThd<int> b2(array, 10);
/*b2.InOrderThreading();
b2.InOrderThd();*/
/*b2.PreOrderThreading();
b2.PreOrderThd();*/
b2.PostOrderThreading();
b2.PostOrderThd();
}
int main()
{
Test3();
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 线索化