您的位置:首页 > 其它

二叉树的线索化和遍历

2018-01-13 13:49 218 查看
包括二叉树的前序,中序,后序线索化和线索化遍历

#pragma once

#include<iostream>
using namespace std;

enum pInfo{ LINK, THREAD };

template<class T>
struct BinTreeThreadNode
{
BinTreeThreadNode(const T data)
:_pLeft(NULL)
, _pRight(NULL)
, _pParent(NULL)
, _data(data)
, _pLeftThread(LINK)
, _pRightThread(LINK)
{}

BinTreeThreadNode<T>* _pLeft;
BinTreeThreadNode<T>* _pRight;
BinTreeThreadNode<T>* _pParent;
T _data;
pInfo _pLeftThread;
pInfo _pRightThread;
};

template <class T>
class BinTreeThread
{
typedef BinTreeThreadNode<T> Node;
typedef Node* pNode;
typedef void(*pFun)(pNode);

public:
BinTreeThread()
:_pRoot(NULL)
{}
void CreateBinTree(T* arr, size_t size, T invalid)
{
size_t index = 0;
_CreateBinTree(_pRoot, arr, size, index, invalid);
}
void PreVisit()//前序遍历
{
_PreVisit(_pRoot, _PrintNode);
}

void InVisit()//中序遍历
{
_InVisit(_pRoot, _PrintNode);
}

void PostVisit()//后序遍历
{
_PostVisit(_pRoot, _PrintNode);
}

void LevelVisit()//层序遍历
{
_LevelVisit(_pRoot, _PrintNode);
}

void PreThread()
{
pNode prev = NULL;
_PreThread(_pRoot,prev);
}

void InThread()
{
pNode prev = NULL;
_InThread(_pRoot,prev);
}

void PostThread()
{
pNode prev = NULL;
_PostThread(_pRoot,prev);
}

void PreThreadVisit()
{
_PreThreadVisit(_pRoot,_PrintNode);
}

void InThreadVisit()
{
_InThreadVisit(_pRoot,_PrintNode);
}

void PostThreadVisit()
{
_PostThreadVisit(_pRoot,_PrintNode);
}
protected:

void _CreateBinTree(pNode& root, T* arr, size_t size, size_t& index, T invalid)
{
if (index < size && invalid != arr[index])
{
root = new Node(arr[index]);

_CreateBinTree(root->_pLeft, arr, size, ++index, invalid);

if (root->_pLeft)
root->_pLeft->_pParent = root;
_CreateBinTree(root->_pRight, arr, size, ++index, invalid);

if (root->_pRight)
root->_pRight->_pParent = root;
}
else
root = NULL;
}

void _PreVisit(pNode& pd, pFun visit)
{
if (pd)
{
visit(pd);
if (pd->_pLeft)
_PreVisit(pd->_pLeft, visit);
if (pd->_pRight)
_PreVisit(pd->_pRight, visit);
}

4000
}

void _InVisit(pNode& pd, pFun visit)
{
if (pd)
{
if (pd->_pLeft)
_InVisit(pd->_pLeft, visit);
visit(pd);
if (pd->_pRight)
_InVisit(pd->_pRight, visit);
}
}

void _PostVisit(pNode& pd, pFun visit)
{
if (pd)
{
if (pd->_pLeft)
_PostVisit(pd->_pLeft, visit);
if (pd->_pRight)
_PostVisit(pd->_pRight, visit);
visit(pd);
}
}

void _LevelVisit(pNode& pd, pFun visit)
{
if (NULL == _pRoot)
return;
queue<pNode> q;
pNode pCur = pd;
q.push(pd);
while (!q.empty())
{
pCur = q.front();
visit(pCur);
if (pCur->_pLeft)
q.push(pCur->_pLeft);
if (pCur->_pRight)
q.push(pCur->_pRight);
q.pop();
}
}

static void _PrintNode(pNode pd)
{
cout << pd->_data << "->";
}

void _PreThread(pNode& pd, pNode& prev)
{
if (NULL == pd)
return;

//线索化当前节点
if (NULL == pd->_pLeft)
{
pd->_pLeft = prev;
pd->_pLeftThread = THREAD;
}
if (prev && NULL == prev->_pRight)
{
prev->_pRight = pd;
prev->_pRightThread = THREAD;
}
prev = pd;

//线索化左子树
if (LINK == pd->_pLeftThread)
_PreThread(pd->_pLeft,prev);

//线索化右子树
if (LINK == pd->_pRightThread)
_PreThread(pd->_pRight,prev);
}

void _InThread(pNode& pd, pNode& prev)
{
if (NULL == pd)
return;

_InThread(pd->_pLeft,prev);

if (NULL == pd->_pLeft)
{
pd->_pLeft = prev;
pd->_pLeftThread = THREAD;
}
if (prev && NULL == prev->_pRight)
{
prev->_pRight = pd;
prev->_pRightThread = THREAD;
}
prev = pd;

if (LINK == pd->_pRightThread)
_InThread(pd->_pRight,prev);
}

void _PostThread(pNode& pd, pNode& prev)
{
if (NULL == pd)
return;

_PostThread(pd->_pLeft, prev);
_PostThread(pd->_pRight, prev);

if (NULL == pd->_pLeft)
{
pd->_pLeft = prev;
pd->_pLeftThread = THREAD;
}
if (prev && NULL == prev->_pRight)
{
prev->_pRight = pd;
prev->_pRightThread = THREAD;
}
prev = pd;
}

void _PreThreadVisit(pNode pd, pFun visit)
{
if (NULL == pd)
return;
pNode pCur = pd;

while (pCur)
{
while (LINK == pCur->_pLeftThread)
{
visit(pCur);
pCur = pCur->_pLeft;
}
visit(pCur);
pCur = pCur->_pRight;
}
}

void _InThreadVisit(pNode pd, pFun visit)
{
if (NULL == pd)
return;

pNode pCur = pd;

while (pCur)
{
while (LINK == pCur->_pLeftThread)
pCur = pCur->_pLeft;
visit(pCur);
while (pCur && THREAD == pCur->_pRightThread)
{
pCur = pCur->_pRight;
visit(pCur);
}

pCur = pCur->_pRight;
}
}

void _PostThreadVisit(pNode pd, pFun visit)
{
if (NULL == pd)
return;

pNode pCur = pd;
pNode prev = NULL;
while (pCur)
{
//找到最左边的节点
while (prev != pCur->_pLeft && LINK == pCur->_pLeftThread)
pCur = pCur->_pLeft;

while (pCur && THREAD == pCur->_pRightThread)
{
visit(pCur);
prev = pCur;
pCur = pCur->_pRight;
}

if (pCur == pd && (prev == pd->_pRight || NULL == pd->_pRight))
{
visit(pCur);
return;
}

while (pCur&& prev == pCur->_pRight)
{
visit(pCur);
prev = pCur;
pCur = pCur->_pParent;
}

if (pCur && LINK == pCur->_pRightThread)
pCur = pCur->_pRight;
}
}

private:
pNode _pRoot;
};

void TestBinTreeThread()
{
BinTreeThread<char> bt;
char arr[] = "ABD###CE##F";/*
A
/ \
B   C
/    /\
D    E  F
*/
bt.CreateBinTree(arr, strlen(arr), '#');//创建树
//bt.PreVisit();
//bt.PreThread();
//cout << endl;
/*bt.InVisit();
bt.InThread();*/
//bt.PostThread();
//bt.PreThreadVisit();

/*cout << endl;
bt.InThreadVisit();*/

bt.PostVisit();
cout << endl;
bt.PostThread();
bt.PostThreadVisit();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线索化 二叉树