您的位置:首页 > 其它

二叉树线索化及其遍历方法

2018-02-27 15:00 239 查看

代码

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<assert.h>

typedef char DataType;

typedef enum { LINK, THREAD }PointFlag;

typedef struct BinTreeNode
{
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
struct BinTreeNode* _pParent;
DataType _data;
PointFlag _leftThread;
PointFlag _rightThread;

}Node, *PNode;

void InitBinTree(PNode pRoot)
{
pRoot = 0;
}

PNode BuyNode(DataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
assert(pNewNode);
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
pNewNode->_pParent = NULL;
pNewNode->_data = data;
pNewNode->_leftThread = LINK;
pNewNode->_rightThread = LINK;

return pNewNode;
}
//二叉树创建
void _CreateBinTree(PNode* pRoot, DataType array[], int size, int* index, DataType invalid)
{
assert(index);
if (*index < size && array[*index] != invalid)
{
*pRoot = BuyNode(array[*index]);

(*index)++;
_CreateBinTree(&(*pRoot)->_pLeft, array, size, index, invalid);
if((*pRoot)->_pLeft)
(*pRoot)->_pLeft->_pParent = (*pRoot);

(*index)++;
_CreateBinTree(&(*pRoot)->_pRight, array, size, index, invalid);
if ((*pRoot)->_pRight)
(*pRoot)->_pRight->_pParent = (*pRoot);
}
}

void CreateBinTree(PNode* pRoot, DataType array[], int size, DataType invalid)
{
int index = 0;
_CreateBinTree(pRoot, array, size, &index, invalid);
}

//前序线索化
void _PreOrderThd(PNode pRoot, PNode* prev)
{
if (pRoot)
{
if (NULL == pRoot->_pLeft)//1.处理当前结点的左指针域
{
pRoot->_pLeft = (*prev);
pRoot->_leftThread = THREAD;
}
if ((*prev) && NULL == (*prev)->_pRight)//2.处理前一个结点的右指针域
{
(*prev)->_pRight = pRoot;
(*prev)->_rightThread = THREAD;
}

(*prev) = pRoot;//3.更新 *prev

if (pRoot->_leftThread == LINK)//4.线索化当前指针的左子树
_PreOrderThd(pRoot->_pLeft, prev);
if (pRoot->_rightThread == LINK)//5.线索化当前指针的右子树
_PreOrderThd(pRoot->_pRight, prev);
}
}

void PreOrderThd(PNode pRoot)
{
PNode prev = NULL;
_PreOrderThd(pRoot, &prev);
}

//中序线索化
void _InOrderThd(PNode pRoot, PNode* prev)
{
if (pRoot)
{
//1.线索化当前结点的左子树
_InOrderThd(pRoot->_pLeft, prev);

//2.处理当前结点的左指针域
if (NULL == pRoot->_pL
c6d5
eft)
{
pRoot->_pLeft = (*prev);
pRoot->_leftThread = THREAD;
}
//3.处理前一个结点的右指针域
if ((*prev) && NULL == (*prev)->_pRight)
{
(*prev)->_pRight = pRoot;
(*prev)->_rightThread = THREAD;
}

//4.更新前一个结点
(*prev) = pRoot;

//5.线索化当前指针的右子树
if(pRoot->_rightThread == LINK)
_InOrderThd(pRoot->_pRight, prev);
}
}

void InOrderThd(PNode pRoot)
{
PNode prev = NULL;
_InOrderThd(pRoot, &prev);
}

//后续线索化
void _PostOrderThd(PNode pRoot, PNode* prev)
{
if (pRoot)
{
_PostOrderThd(pRoot->_pLeft, prev);//线索化当前结点的左子树
_PostOrderThd(pRoot->_pRight, prev);//线索化当前结点的右子树

if (NULL == pRoot->_pLeft)//处理当前结点的左指针域
{
pRoot->_pLeft = (*prev);
pRoot->_leftThread = THREAD;
}
if ((*prev) && NULL == (*prev)->_pRight)//处理前一个结点的右指针域
{
(*prev)->_pRight = pRoot;
(*prev)->_rightThread = THREAD;
}
(*prev) = pRoot;//更新前一个结点指向下一个
}
}

void PostOrderThd(PNode pRoot)
{
PNode prev = NULL;
_PostOrderThd(pRoot, &prev);
}

//前序递归遍历
void PreOrderD(PNode pRoot)
{
if (pRoot)
{
printf("%c ", pRoot->_data);
PreOrderD(pRoot->_pLeft);
PreOrderD(pRoot->_pRight);
}
}

//线索化前序遍历
void PreOrder(PNode pRoot)
{
PNode pCur = pRoot;
while (pCur)
{
while (pCur->_leftThread == LINK)
{
printf("%c ", pCur->_data);
pCur = pCur->_pLeft;
}
printf("%c ", pCur->_data);

pCur = pCur->_pRight;
}
}
//中序递归遍历
void InOrderD(PNode pRoot)
{
if (pRoot)
{
InOrderD(pRoot->_pLeft);
printf("%c ", pRoot->_data);
InOrderD(pRoot->_pRight);
}
}
//线索化中序遍历
void InOrder(PNode pRoot)
{
PNode pCur = pRoot;

while (pCur)
{
while (pCur->_leftThread == LINK)//取最左边的结点
{
pCur = pCur->_pLeft;
}
//当且结点的左子树已处理完毕
printf("%c ", pCur->_data);//处理当前结点

while (pCur->_rightThread == THREAD)//开始处理后续结点,转移到右子树(访问连载一起的后续结点)
{
pCur = pCur->_pRight;
printf("%c ", pCur->_data);
}
pCur = pCur->_pRight;//开始处理当前结点的右子树
}

}

//后续递归遍历
void PostOrderD(PNode pRoot)
{
if (pRoot)
{
PostOrderD(pRoot->_pLeft);
PostOrderD(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
}
//线索化后续遍历
void PostOrder(PNode pRoot)
{
PNode pCur = pRoot;
PNode prev = NULL;

while (pCur)
{

while (pCur && pCur->_leftThread == LINK)//找到最左边的结点
pCur = pCur->_pLeft;

while (pCur->_rightThread == THREAD)//访问连载一起的后续结点
{
printf("%c ", pCur->_data);
prev = pCur;
pCur = pCur->_pRight;
}
if (pCur == pRoot && (NULL == pCur->_pRight || prev == pCur->_pRight))//根节点
{
printf("%c ", pCur->_data);
return;
}
while (pCur && pCur->_pRight == prev)//访问当前结点
{
printf("%c ", pCur->_data);
prev = pCur;
pCur = pCur->_pParent;
}
if (pCur && pCur->_rightThread == LINK)//开始访问右子树
{
pCur = pCur->_pRight;
}
}
}

int main()
{
char array[] = { 'A','B','D','#','#','#','C','E','#','#','F' };
PNode pRoot = NULL;

CreateBinTree(&pRoot, array, sizeof(array) / sizeof(array[0]), '#');

//前序线索化
PreOrderD(pRoot);
printf("\n");
PreOrderThd(pRoot);
PreOrder(pRoot);
printf("\n");

//中序线索化
//InOrderD(pRoot);
//printf("\n");
//InOrderThd(pRoot);
//InOrder(pRoot);
//printf("\n");

//后续线索化
//PostOrderD(pRoot);
//printf("\n");
//PostOrderThd(pRoot);
//PostOrder(pRoot);
//printf("\n");

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: