BinaryTreeThreading.h
#pragma once
#include<iostream>
using namespace std;
enum PointerTag
{
LINK, //指针,指向左右孩子
THREAD, //线索,指向前驱或后继
};
template<class T>
struct BinTreThrNode
{
BinTreThrNode(const T& x)
:_value(x)
, _leftChild(NULL)
, _rightChild(NULL)
, _LTag(LINK)
, _RTag(LINK)
{}
T _value;
BinTreThrNode<T>* _leftChild;
BinTreThrNode<T>* _rightChild;
PointerTag _LTag;
PointerTag _RTag;
};
template<class T>
class BinaryTreeThread
{
public:
BinaryTreeThread(T* arr, size_t size)
{
int index = 0;
_CreateTree(_root,arr,size,index);
}
void InOrderThearding() //中序遍历线索化
{
BinTreThrNode<T>* prev = NULL;
_InOrderThearding(_root,prev);
}
void PrevOrderThearding() //前序遍历线索化
{
BinTreThrNode<T>* prev = NULL;
_PrevOrderThearding(_root, prev);
}
void PostOrderThearding() //后序遍历线索化
{
BinTreThrNode<T>* prev = NULL;
_PostOrderThearding(_root, prev);
}
void InOrder()
{
cout << "中序遍历:";
BinTreThrNode<T>* cur = _root;
while (cur)
{
while (cur && cur->_LTag != THREAD)
{
cur = cur->_leftChild;
}
cout << cur->_value << " ";
if (cur->_RTag != THREAD)
{
cur = cur->_rightChild;
}
else
{
cur = cur->_rightChild;
cout << cur->_value << " ";
while (cur->_RTag == THREAD) //防止死循环
{
cur = cur->_rightChild;
cout << cur->_value << " ";
}
cur = cur->_rightChild;
}
}
cout << endl;
}
void PrevOrder()
{
cout << "前序遍历:";
BinTreThrNode<T>* cur = _root;
while (cur)
{
while (cur->_LTag != THREAD)
{
cout << cur->_value<<" ";
cur = cur->_leftChild;
}
cout << cur->_value<<" ";
cur = cur->_rightChild;
}
}
void PostOrder()
{
cout << "后序遍历:";
BinTreThrNode<T>* cur = _root;
BinTreThrNode<T>* prev = _root;
while (cur)
{
while (cur->_LTag != THREAD && prev->_rightChild != cur)
{
cur = cur->_leftChild;
}
cout << cur->_value << " ";
if (cur->_RTag == THREAD)
{
prev = cur;
}
if (prev->_rightChild == cur && cur != _root) //防止死循环
{
cur = _root;
}
if (cur->_rightChild != prev)
{
cur = cur->_rightChild;
}
else
{
return;
}
}
}
private:
void _CreateTree(BinTreThrNode<T>*& root, T* arr, size_t size,int& index) //index要用引用
{
if (arr[index] != '#' && index < size)
{
root = new BinTreThrNode<T>(arr[index]);
_CreateTree(root->_leftChild,arr,size,++index);
_CreateTree(root->_rightChild,arr,size,++index);
}
}
void _InOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
{
BinTreThrNode<T>* cur = root;
if (cur && cur->_leftChild)
{
_InOrderThearding(cur->_leftChild, prev);
}
if (cur->_leftChild == NULL)
{
cur->_leftChild = prev;
cur->_LTag = THREAD;
}
if (prev && prev->_rightChild == NULL)
{
prev->_rightChild = cur;
prev->_RTag = THREAD;
}
prev = cur;
if (cur && cur->_rightChild)
{
_InOrderThearding(cur->_rightChild, prev);
}
}
void _PrevOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
{
BinTreThrNode<T>* cur = root;
if (cur->_leftChild == NULL)
{
cur->_LTag = THREAD;
cur->_leftChild = prev;
}
if (prev && prev->_rightChild == NULL)
{
prev->_rightChild = cur;
prev->_RTag = THREAD;
}
prev = cur;
if (cur && cur->_LTag != THREAD)
{
_PrevOrderThearding(cur->_leftChild, prev);
}
if (cur->_rightChild && cur->_RTag != THREAD)
{
_PrevOrderThearding(cur->_rightChild, prev);
}
}
void _PostOrderThearding(BinTreThrNode<T>*& root, BinTreThrNode<T>*& prev)
{
BinTreThrNode<T>* cur = root;
if (cur)
{
_PostOrderThearding(cur->_leftChild, prev);
_PostOrderThearding(cur->_rightChild, prev);
if (cur->_leftChild == NULL)
{
cur->_LTag = THREAD;
cur->_leftChild = prev;
}
if (prev && prev->_rightChild == NULL && prev != cur)
{
prev->_rightChild = cur;
prev->_RTag = THREAD;
}
prev = cur;
}
}
private:
BinTreThrNode<T>* _root;
};
main.cpp
#include"BinaryTreeThreading.h"
void Test()
{
int arr[] = { 1, 2, 3, '#', '#', '#', 4, 5 };
BinaryTreeThread<int> bt(arr, 8);
//bt.InOrderThearding();
//bt.InOrder();
/*bt.PrevOrderThearding();
bt.PrevOrder();*/
bt.PostOrderThearding();
bt.PostOrder();
}
void Test1()
{
int arr[] = { 1, 2, 3, '#', '#', 4,'#' ,'#', 5 ,6};
BinaryTreeThread<int> bt(arr, 10);
//bt.InOrderThearding();
//bt.InOrder();
/*bt.PrevOrderThearding();
bt.PrevOrder();*/
bt.PostOrderThearding();
bt.PostOrder();
}
int main()
{
Test();
getchar();
return 0;
}