//ThreadBiTree.h
#ifndef BITREE_H
#define BITREE_H
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
#define OVERFLOW -2
#define SUCCESS 0
#pragma pack(push)
#pragma pack(4)
struct _Node
{
int iValue;
struct _Node* pLChild;
struct _Node* pRChild;
int bLTag;//0:pLChild指向结点左孩子 1:pRChild指向结点前驱
int bRTag;//0:pRChild指向结点右孩子 2:pRChild指向结点后继
};
typedef struct _Node Node, *BiThrTree;
enum PointerTag{ LINK, THREAD };
#pragma pack(pop)
BiThrTree InitTree();
Node* CreateNode( int iValue );
Node* AppendLeftChild( Node* pNode, Node* pValue );
Node* AppendRightChild( Node* pNode, Node* pValue );
void PrintNode( Node* pNode );
void PreTraverseTree( Node* pNode );
void MidTraverseTree( Node* pNode );
void PostTraverseTree( Node* pNode );
void Traverese( Node* pNode );
void InThreading( BiThrTree pNode );
BiThrTree InOrderThreading( BiThrTree pTree );
void InOrderTraverse( BiThrTree pTree );
#endif
//ThreadBiTree.c
#include "ThreadBiTree.h"
BiThrTree InitTree()
{//初始化树
BiThrTree pTree = (BiThrTree)malloc( sizeof( Node ) );
if( !pTree )
return NULL;
return pTree;
}
Node* CreateNode( int iValue )
{
Node* pNode = (Node*)malloc( sizeof( Node ) );
if( !pNode )
return NULL;
pNode->pLChild = NULL;
pNode->pRChild = NULL;
pNode->iValue = iValue;
//默认设置为链接
pNode->bLTag = LINK;
pNode->bRTag = LINK;
return pNode;
}
Node* AppendLeftChild( Node* pNode, Node* pValue )
{//追加孩子结点
if( !pNode || !pValue )
return NULL;
if( pNode->pLChild )
return NULL;
pNode->pLChild = pValue;
pValue->pLChild = NULL;
pValue->pRChild = NULL;
return pValue;
}
Node* AppendRightChild(Node* pNode, Node* pValue )
{//追加孩子结点
if( !pNode || !pValue )
return NULL;
if( pNode->pRChild )
return NULL;
pNode->pRChild = pValue;
pValue->pLChild = NULL;
pValue->pRChild = NULL;
return pValue;
}
void PrintNode( Node* pNode )
{//输出结点
if( pNode )
printf( "%d ", pNode->iValue );
}
void PreTraverseTree( Node* pNode )
{//前序遍历树
if( !pNode )
return;
PrintNode( pNode );//根
PreTraverseTree( pNode->pLChild );
PreTraverseTree( pNode->pRChild );
}
void MidTraverseTree( Node* pNode )
{
if( !pNode )
return;
MidTraverseTree( pNode->pLChild );
PrintNode( pNode );
MidTraverseTree( pNode->pRChild );
}
void PostTraverseTree( Node* pNode )
{//后序遍历树
if( !pNode )
return;
PostTraverseTree( pNode->pLChild );
PostTraverseTree( pNode->pRChild );
PrintNode( pNode );
}
void Traverese( Node* pNode )
{
if( !pNode )
return;
puts( "Pre" );
PreTraverseTree( pNode );
puts( "" );
puts( "Mid" );
MidTraverseTree( pNode );
puts( "" );
puts( "Post" );
PostTraverseTree( pNode );
puts( "" );
}
static Node* pPre = NULL;
BiThrTree InOrderThreading( BiThrTree pTree )
{
if( !pTree )
return NULL;
if( !pTree->pLChild )
{
pTree->bLTag = THREAD;
pTree->bRTag = THREAD;
pTree->pRChild = NULL;
}
else
{
pTree->bLTag = LINK;
pTree->bRTag = THREAD;
pTree->pRChild = pTree;//右子回指
pPre = pTree->pLChild;
//中序线索化二叉树
InThreading( pPre );
pPre->pRChild = pTree;
pPre->bRTag = THREAD;
pTree->pRChild = pPre;
}
return pTree;
}
void InThreading( Node* pNode )
{
if( pNode )
{
if( pNode->pLChild )
InThreading( pNode->pLChild );
if( !pNode->pLChild )
{
pNode->bLTag = THREAD;
pNode->pLChild = pPre;
}
if( !pPre->pRChild )
{
pPre->bRTag = THREAD;
pPre->pRChild = pNode;
}
pPre = pNode;
if( pNode->pRChild )
InThreading( pNode->pRChild );
}
}
void InOrderTraverse( BiThrTree pTree )
{
if( !pTree || !pTree->pLChild )
return;
Node* pNode = pTree->pLChild;
while( pNode != pTree )
{
while( pNode->bLTag == LINK )
{
pNode = pNode->pLChild;
}
PrintNode( pNode );
while( pNode->bRTag == THREAD && pNode->pRChild != pTree )
{
pNode = pNode->pRChild;
PrintNode( pNode );
}
pNode = pNode->pRChild;
}
}
int main( int argc, char* argv[] )
{
BiThrTree pTree = InitTree();
pTree->pLChild = CreateNode( 0 );
//pTree->pRChild = pTree;//右子回指
Node* pLeft = AppendLeftChild( pTree->pLChild, CreateNode( 1 ));
Node* pRight = AppendRightChild( pTree->pLChild, CreateNode( 2 ));
AppendLeftChild( pLeft, CreateNode( 3 ));
AppendRightChild( pLeft, CreateNode( 4 ) );
AppendLeftChild( pRight, CreateNode( 5 ));
pRight = AppendRightChild( pRight, CreateNode( 6 ));
Traverese( pTree->pLChild );
pTree = InOrderThreading( pTree );
puts( "InOrderThreadingTraverse:" );
InOrderTraverse( pTree );
puts( "" );
return 0;
}