1)二叉树的前序,中序,后序,层次遍历的原理和实现
void _PreOrder(BinaryTreeNode<T> *root)
{
if(root == NULL){
return;
}
cout<<root->data<<" ";
_PreOrder(root->_left);
_PreOrder(root->_right);
}
void _InOrder(BinaryTreeNode<T> *root)
{
if(root == NULL){
return;
}
_InOrder(root->_left);
cout<<root->data<<" ";
_InOrder(root->_right);
}
void _PostOrder(BinaryTreeNode<T> *root)
{
if(root == NULL){
return;
}
_PostOrder(root->_left);
_PostOrder(root->_right);
cout<<root->data<<" ";
}
void _LevelOrder(BinaryTreeNode<T> *root)
{
if(root == NULL){
cout<<"NULL";
return;
}
queue<BinaryTreeNode<T> *> s;
s.push(root);
while(!s.empty()){
BinaryTreeNode<T> *tmp = s.front();
cout<<tmp->data<<" ";
s.pop();
if(tmp->_left != NULL){
s.push(tmp->_left);
}
if(tmp->_right != NULL){
s.push(tmp->_right);
}
}
}
void PreOrder_NonR()
{
stack<BinaryTreeNode<T> *> s;
if(_root == NULL){
return;
}
s.push(_root);
while(!s.empty()){
BinaryTreeNode<T> *top =s.top();
s.pop();
cout<<top->data<<" ";
if(top->_right != NULL)
s.push(top->_right);
if(top->_left != NULL)
s.push(top->_left);
}
cout<<endl;
}
void InOrder_NonR()
{
stack<BinaryTreeNode<T> *> s;
BinaryTreeNode<T> *cur = _root;
if(_root == NULL){
return;
}
while(cur || !s.empty()){
while(cur){
s.push(cur);
cur = cur->_left;
}
BinaryTreeNode<T> *top = s.top();
cout<<top->data<<" ";
s.pop();
cur = top->_right;
}
cout<<endl;
}
void PostOrder_NonR()
{
stack<BinaryTreeNode<T> *> s;
BinaryTreeNode<T> *cur = _root;
BinaryTreeNode<T> *PreVisited = NULL;
if(_root == NULL){
return;
}
while(cur || !s.empty()){
while(cur){
s.push(cur);
cur = cur->_left;
}
BinaryTreeNode<T> *top = s.top();
if(top->_right == NULL || top->_right == PreVisited){
cout<<top->data<<" ";
s.pop();
PreVisited = top;
}else{
cur = top->_right;
}
}
}
2)二叉树的线索化的实现,为什么要有线索化?
二叉树是一种非线性结构,遍历二叉树几乎都是通过递归或者用栈辅助实现非递归的遍历。用二叉树作为存储结构时,取到一个节点,只能获取节点的左孩子和右孩子,不能直接得到节点的任一遍历序列的前驱或者后继。
为了保存这种在遍历中需要的信息,我们利用二叉树中指向左右子树的空指针来存放节点的前驱和后继信息。
enum Tag{
THREAD,
LINK,
};
template<typename T>
struct BinaryTreeNode{
T data;
BinaryTreeNode *_left;
BinaryTreeNode *_right;
Tag _leftTag;
Tag _rightTag;
BinaryTreeNode(T _data)
:data(_data)
,_left(NULL)
,_right(NULL)
,_leftTag(LINK)
,_rightTag(LINK)
{}
};
线索化:
<span style="white-space:pre"> </span>void _InOrderThreading(BinaryTreeNode<T> *cur,BinaryTreeNode<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(BinaryTreeNode<T> *cur,BinaryTreeNode<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(BinaryTreeNode<T> *cur,BinaryTreeNode<T> * & prev)
{
if(cur == NULL)
return;
_PostOrderThreading(cur->_left,prev);
_PostOrderThreading(cur->_right,prev);
if(cur->_left == NULL) //如果左为空,对左进行线索化
{
cur->_leftTag = THREAD;
cur->_left = prev;
}
if(prev && prev->_right == NULL) //如果右为空,对右进行线索化
{
prev->_rightTag = THREAD;
prev->_right = cur;
}
prev = cur;
}
线索化后的遍历
<span style="white-space:pre"> </span>void InOrderThd()
{
BinaryTreeNode<T> *cur = _root;
while(cur)
{
while( cur && cur->_leftTag == LINK) //找到最左结点
cur = cur->_left;
cout<<cur->data<<" ";
if(cur->_rightTag == THREAD){
cur = cur->_right;
cout<<cur->data<<" ";
}
cur = cur->_right;
}
}
<span style="white-space:pre"> </span>void PreOrderThd()
{
BinaryTreeNode<T> *cur = _root;
while(cur)
{
while(cur->_leftTag == LINK){
cout<<cur->data<<" ";
cur = cur->_left;
}
cout<<cur->data<<" ";
cur = cur->_right;
}
}
<span style="white-space:pre"> </span>void PostOrderThd()
{
stack<BinaryTreeNode<T> *> s;
BinaryTreeNode<T> *cur = _root;
while(cur)
{
while(cur->_rightTag == LINK){
s.push(cur);
cur = cur->_right;
}
s.push(cur);
cur = cur->_left;
}
while(s.size() > 0){
BinaryTreeNode<T> *tmp = s.top();
cout<<tmp->data<<" ";
s.pop();
}
}