C语言:线索二叉树的线索化及其遍历实现

       前序和中序遍历都实现了,后序线索化还不是很明白!如有大神看到,望指正!不胜感激!

// 中序线索二叉树实现.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
using namespace std;
#define ElementType char
typedef enum{ Link, Thread } PointerTag;
//线索存储标志位
//Link(0):表示指向左右孩子的指针
//Thread(1):表示指向前驱和后继的线索
typedef struct BiThrNode
{
	ElementType Data;
	struct BiThrNode *Left;
	struct BiThrNode *Right;
	PointerTag Ltag;
	PointerTag Rtag;
}BiThrNode, *BiThrTree;
//全局变量,始终指向刚刚问过的节点
BiThrNode *pre;
//创建一个二叉树:利用前序遍历创建二叉树
//函数声明
void CreatTree(BiThrTree *BT);
void DestroyBiTree(BiThrTree &T);
void DestroyBiThrTree(BiThrTree &Thrt);
//中序线索化二叉树,并且实现中序遍历操作函数定义
void InThreding(BiThrTree BT);
void InorderThreding(BiThrTree *p, BiThrTree T);
void InOrderTraverse(BiThrTree T);
void InOrderTraverse_Iter(BiThrTree T);

//前序线索化二叉树,并且实现前序遍历操作函数定义
void PreThreding(BiThrTree BT);
void PreorderThreding(BiThrTree *p, BiThrTree T);
void PreOrderTraverse(BiThrTree T);
void PreOrderTraverse_Iter(BiThrTree T);

//后序线索化二叉树,并且实现后序遍历操作函数定义
void PostThreding(BiThrTree BT);
void PostorderThreding(BiThrTree *p, BiThrTree T);
void PostOrderTraverse(BiThrTree T);
void PostOrderTraverse_Iter(BiThrTree T);

//函数定义
void CreatTree(BiThrTree *BT)
{
	char ch;
	cin >> ch;
	if (ch == '#') *BT = NULL;
	else
	{
		*BT = (BiThrNode*)malloc(sizeof(struct BiThrNode));
		(*BT)->Data = ch;
		(*BT)->Ltag = Link;
		(*BT)->Rtag = Link;
		CreatTree(&(*BT)->Left);
		CreatTree(&(*BT)->Right);
	}
}
void PostOrderTraverse(BiThrTree T)
{
	if (T)
	{
		PostOrderTraverse(T->Left);
		PostOrderTraverse(T->Right);
		cout << T->Data;
	}
}
void  InOrderTraverse(BiThrTree T)
{
	if (T)
	{
		InOrderTraverse(T->Left);
		cout << T->Data;
		InOrderTraverse(T->Right);
	}
}
void  PreOrderTraverse(BiThrTree T)
{
	if (T)
	{
		cout << T->Data;
		PreOrderTraverse(T->Left);
		PreOrderTraverse(T->Right);

	}
}
void DestroyBiTree(BiThrTree &T)
{
	if (T)  // 非空树  
	{
		if (T->Ltag == Link)                // 有左孩子  
			DestroyBiTree(T->Left);         // 销毁左孩子子树  
		if (T->Rtag == Link)                // 有右孩子  
			DestroyBiTree(T->Right);        // 销毁右孩子子树  
		free(T);    // 释放根结点  
		T = NULL;   // 空指针赋0  
	}
}
// 初始条件:线索二叉树Thrt存在。操作结果:销毁线索二叉树Thrt  
void DestroyBiThrTree(BiThrTree &T)
{
	if (T)             // 头结点存在  
	{
		if (T->Left)    // 根结点存在  
		{
			DestroyBiTree(T->Left); // 递归销毁头结点lchild所指二叉树  
		}
		free(T);     // 释放头结点  
		T = NULL;    // 线索二叉树Thrt指针赋0  
	}
}
//前序线索化二叉树,并且实现前序遍历操作函数定义
void PreThreding(BiThrTree BT)
{
	if (BT)
	{
		if (!BT->Left)
		{
			BT->Ltag = Thread;
			BT->Left = pre;
		}
		if (!pre->Right)
		{
			pre->Right = BT;
			pre->Rtag = Thread;
		}
		pre = BT;
		if (BT->Ltag == Link)
			PreThreding(BT->Left);//递归左孩子线索化
		if (BT->Rtag == Link)
			PreThreding(BT->Right);//递归右孩子线索化
	}
}
void PreorderThreding(BiThrTree *p, BiThrTree T)
{//p结点为头结点,T结点为树根结点
	*p = (BiThrNode*)malloc(sizeof(struct BiThrNode));
	(*p)->Ltag = Link;
	(*p)->Rtag = Thread;
	(*p)->Right = *p;
	if (!T)  (*p)->Left = *p;
	else
	{
		(*p)->Left = T;
		pre = *p;
		PreThreding(T);
		pre->Right = *p;
		pre->Rtag = Thread;
		(*p)->Right = pre;
	}
}
void PreOrderTraverse_Iter(BiThrTree T)
{
	BiThrTree p = T->Left;
	while (p != T)
	{
		cout << p->Data;
		if (p->Ltag == Link)
			p = p->Left;
		else
			p = p->Right;
	}
}
//与前序有关的函数实现结束

//中序线索化二叉树,并且实现中序遍历操作
//中序遍历线索化的过程
void InThreding(BiThrTree BT)
{
	if (BT)
	{
		InThreding(BT->Left);//递归左孩子线索化
		//结点处理
		if (!BT->Left)      //如果该结点没有左孩子,
		{
			BT->Ltag = Thread;
			BT->Left = pre;
		}
		if (!pre->Right)
		{
			pre->Rtag = Thread;
			pre->Right = BT;
		}
		pre = BT;
		InThreding(BT->Right);//递归右孩子线索化
	}
}
void InorderThreding(BiThrTree *p, BiThrTree T)
{//p结点为头结点,T结点为树根结点
	*p = (BiThrNode*)malloc(sizeof(struct BiThrNode));//创建一个头结点
	(*p)->Ltag = Link;
	(*p)->Rtag = Thread;
	(*p)->Right = *p;          //有指针回指
	if (!T)  (*p)->Left = *p;   //若二叉树为空,则做指针回指
	else
	{
		(*p)->Left = T;        //若二叉树不为空,Left指向根结点
		pre = *p;
		InThreding(T);       //中序遍历进行中序线索化
		//最后一个结点线索化
		pre->Rtag = Thread;
		pre->Right = *p;    //终端结点指向头结点
		(*p)->Right = pre;  //头结点的右指针指向终端结点
	}

}
//中序遍历二叉树,非递归实现
void InOrderTraverse_Iter(BiThrTree T)
{
	BiThrTree p;
	p = T->Left;      //p指向根结点T
	while (p != T)     //二叉树非空或遍历未结束
	{
		while (p->Ltag == Link)  //访问左子树为空的结点
		{
			p = p->Left;
		}
		cout << p->Data;
		while ((p->Rtag == Thread)&&(p->Right != T))  //p的Right指向后继,访问p结点的后继
		{
			p = p->Right;
			cout << p->Data;
		}
		p = p->Right;   //p的Right指向右孩子
	}
}
//与中序有关的函数实现结束

//后序线索化二叉树,并且实现后序遍历操作函数定义
void PostThreding(BiThrTree BT)
{
	if (BT)
	{
		PostThreding(BT->Left);
		PostThreding(BT->Right);
		if (!BT->Left)
		{
			BT->Ltag = Thread;
			BT->Left = pre;
		}
		if (!pre->Right)
		{
			pre->Rtag = Thread;
			pre->Right = BT;
		}
		pre = BT;
	}
}
void PostorderThreding(BiThrTree *p, BiThrTree T)
{
	//p结点为头结点,T结点为树根结点
	*p = (BiThrNode*)malloc(sizeof(struct BiThrNode));
	(*p)->Ltag = Link;
	(*p)->Rtag = Thread;

	if (!T)  (*p)->Left = (*p)->Right = *p;
	else
	{
		(*p)->Left = (*p)->Right = *p;
		pre = *p;
		PostThreding(T);
		if (pre->Rtag != Link)  // 最后一个结点没有右孩子  
		{
			pre->Right = *p;  // 最后一个结点的后继指向头结点  
			pre->Rtag = Thread;
		}
	}
}
void PostOrderTraverse_Iter(BiThrTree T)
{
	BiThrTree p =T->Left;
	while (p->Ltag == Link || p->Rtag == Link)   //有左孩子先访问左孩子,没有左孩子先访问右孩子  
	{
		while (p->Ltag == Link)
			p = p->Left;
		if (p->Rtag == Link)                //访问左孩子为空的结点的右孩子  
			p = p->Right;
	}
	cout << p->Data;
	while (p != T)                        //p不为根结点  
	{
		if (p->Rtag == Link)              //若p是有兄弟的左孩子  
		{
			if (pre->Rtag == Thread || p == pre->Right) //若p是双亲的右孩子或是独生左孩子,则后继为双亲  
				p = pre;
			else
			{
				p = pre->Right;              //后继为双亲的右子树上按照后序遍历访问的第一个结点。  
				while (p->Ltag == Link || p->Rtag == Link)
				{
					if(p->Ltag == Link)
						p = p->Left;
					if (p->Rtag == Link)
						p = p->Right;
				}
			}
		}
		else
			p = p->Right;             //p指向后继  
		cout << p->Data;
	}
}
//与后序有关的函数实现结束
int _tmain(int argc, _TCHAR* argv[])
{
	BiThrTree T = NULL;
	BiThrTree BT = NULL;
	BiThrTree A = NULL;
	BiThrTree BA = NULL;
	BiThrTree D = NULL;
	BiThrTree BD = NULL;
	cout << "按照前序遍历创建二叉树:" << endl;
	CreatTree(&T);
	cout << "中序遍历:";
	InOrderTraverse(T);
	cout << endl;
	cout << "中序线索化!" << endl;
	InorderThreding(&BT, T);
	cout << "中序线索化后输出:";
	InOrderTraverse_Iter(BT);
	cout << endl;
	DestroyBiThrTree(BT);

	cout << "按照前序遍历创建二叉树:" << endl;
	CreatTree(&A);
	cout << "前序遍历:";
	PreOrderTraverse(A);
	cout << endl;
	cout << "前序线索化!" << endl;
	PreorderThreding(&BA, A);
	cout << "前序线索化后输出:";
	PreOrderTraverse_Iter(BA);
	cout << endl;
	DestroyBiThrTree(BA);

	cout << "按照前序遍历创建二叉树:" << endl;
	CreatTree(&D);
	cout << "后序遍历:";
	PostOrderTraverse(D);
	cout << endl;
	cout << "后序线索化!" << endl;
	PostorderThreding(&BD, D);
	cout << "后序线索化后输出:";
	PostOrderTraverse_Iter(BD);
	DestroyBiThrTree(BD);
	cout << endl;
	return 0;
}


你可能感兴趣的:(数据结构与算法设计)