线索二叉树非递归
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef char elemType;
typedef struct BiTNode
{
elemType data;
struct BiTNode *lchild, *rchild;
int LTag, RTag;
}BiThreadNode, *BiThreadTree;
void visit(elemType x); /* 输出元素x */
BiThreadTree createBiThreadTree(); /* 先序输入节点的值,构造二叉树 */
BiThreadNode *CreateInThrTree(BiThreadTree T);/* 创建中序线索二叉树 */
void InThreading(BiThreadTree T); /* 中序遍历线索化 */
void ThrInOrderTraverse(BiThreadTree T); /* 遍历中序线索二叉树 */
BiThreadNode * pre; /* 当前访问节点的前驱 */
int main(void)
{
BiThreadTree root;
printf("请按先序顺序输入节点值,输入‘#’代表节点为空:\n");
root = createBiThreadTree();
BiThreadNode * ThrHead = CreateInThrTree(root);
ThrInOrderTraverse(ThrHead);
return 0;
}
void visit(elemType x)
{
printf("%c, ", x);
}
BiThreadTree createBiThreadTree()
{
BiThreadNode * T;
char ch;
if ((ch = getchar()) == '#') T = NULL;
else
{
T = (BiThreadNode *)malloc(sizeof(BiThreadNode));
T->data = ch;
T->lchild = createBiThreadTree();
T->rchild = createBiThreadTree();
}
return T;
}
void InThreading(BiThreadTree T)
{
if (T != NULL)
{
InThreading(T->lchild); /* 线索化左子树 */
if (T->lchild == NULL) /* 左孩子为空,则lchild指向前驱pre */
{
T->LTag = 1;
T->lchild = pre;
}
else T->LTag = 0;
if (pre->rchild == NULL)/* 前驱pre右孩子为空,则当前节点为前驱pre的后继 */
{
pre->RTag = 1;
pre->rchild = T;
}
else pre->RTag = 0;
pre = T;
InThreading(T->rchild);/* 线索化右子树 */
}
}
BiThreadNode *CreateInThrTree(BiThreadTree T)
{
BiThreadNode * ThrHead; /* 中序线索二叉树头节点(非根节点) */
/****************************************************
* 设中序遍历第一个节点、最后一个节点分别为first、last
* 则:first->lchild指向ThrHead
* last->rchild指向ThrHead
* ThrHead->lchild:指向根节点
* ThrHead->rchild:指向last
****************************************************/
ThrHead = (BiThreadNode *)malloc(sizeof(BiThreadNode));
ThrHead->RTag = 1;
ThrHead->rchild = ThrHead;/* 先将ThrHead->rchild指向自身 */
ThrHead->LTag = 0;
if (T == NULL) ThrHead->lchild = ThrHead;/* 若根节点为空,则ThrHead->lchild指向自身 */
else
{
ThrHead->lchild = T;
pre = ThrHead; /* 将ThrHead赋给pre,pre为中序线索树中first节点前驱 */
InThreading(T); /* 二叉树线索化完毕,pre指向last节点 */
pre->rchild = ThrHead;/* 将ThrHead作为last节点后继 */
pre->RTag = 1;
ThrHead->rchild = pre;/* 将ThrHead->rchild指向pre(last) */
}
return ThrHead;
}
void ThrInOrderTraverse(BiThreadTree ThrHead)
{
BiThreadNode * temp = ThrHead->lchild; /* 让temp指向根节点 */
while (temp != ThrHead)
{
while (temp->LTag == 0) temp = temp->lchild;/* 向左走到尽头 */
visit(temp->data);
while (temp->RTag == 1 && temp->rchild != ThrHead)
{/* 若当前节点无右子树且后继不是头节点,则输出后继的值 */
temp = temp->rchild;
visit(temp->data);
}
temp = temp->rchild; /* 遍历右子树 */
}
}
线索二叉树递归
#include<stdio.h>
#include<stdlib.h>
//定义结构体
typedef struct node{
char data;
struct node *left, *right;
int Lflag;
int Rflag; //左右标志是左右子树还是前驱后继节点,Link = 0: 左右子树,, Thread =1;前驱后继节点
}Node,*TreeNode;
TreeNode pre = NULL;
//利用前序创建树,若使用中序或者后序,只需调正一下语句位置
void createTree(TreeNode *T){
char data;
scanf("%c",&data);
if(T!=NULL){
if(data != '#'){
//分配内存
if(!((*T) = (Node *)malloc(sizeof(Node)))){
printf("申请内存失败!");
return;
}//赋值
else{
(*T) ->data = data;
createTree(&((*T)->left)); //初始化左子树
createTree(&((*T)->right));
}
}else{
(*T) = NULL;
}
}
}
//中序遍历
void mid_SearchTest(TreeNode T){
if(T){
mid_SearchTest(T->left);
printf("%c ", T->data);
mid_SearchTest(T->right);
}
}
//中序对二叉树进行线索化
void mid_InThreading(TreeNode T){
if(T){
mid_InThreading(T ->left); //递归左子树线索化
//如果当前节点没有左孩子,则左标志设为1,指向上一个节点pre
if(!(T->left)){
T ->Lflag = 1;
T ->left = pre;
}
//如果pre没有右节点,则右标志为1,指向下一个节点
if(pre != NULL && pre ->right ==NULL){
pre ->Rflag = 1;
pre ->right = T;
}
pre = T; //pre指向当前节点
mid_InThreading(T ->right); //递归右子树
}
}
//中序遍历线索二叉树
void mid_Search(TreeNode T){
while(T){
//一直找左子树,最后一个左节点输出
while(T ->Lflag != 1){
T = T ->left;
}
printf("%c ",T->data);
//当节点右标志为1时,直接找到其后继节点
while(T->Rflag == 1 && T ->right != NULL){
T = T->right;
printf("%c ",(T ->data));
}
//否则,找到其右子树的最下边的左节点遍历
T =T->right;
}
}
int main(){
TreeNode T;
printf("请输入mid遍历的序列:\n");
createTree(&T);
printf("\n");
mid_InThreading(T);
printf("请输入mid遍历的序列:\n");
mid_Search(T);
return 0;
}