common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//Status Equal(int a, int b);
#endif
BiThrTree.h
#ifndef _BITHRTREE_H_
#define _BITHRTREE_H_
typedef char TElemType;
//二叉树的二叉线索存储表示
//typedef enum PointerTag{Link, Thread}; //Link==0:指针, Thread==1:线索
typedef enum{Link, Thread} PointerTag; //Link==0:指针, Thread==1:线索
typedef struct BiThrNode
{
TElemType data;
struct BiThrNode *lchild, *rchild; //左右孩子指针
PointerTag LTag, RTag; //左右标志
}BiThrNode, *BiThrTree;
Status CreateBiThrTree(BiThrTree *T);
void InThreading(BiThrTree p);
Status InOrderThreading(BiThrTree *Thrt, BiThrTree T);
Status InOrderTraverse_Thr(BiThrTree T, Status (* Visit)(TElemType e));
#endif
#include "common.h"
#include "BiThrTree.h"
#include "stdio.h"
#include "stdlib.h"
BiThrTree pre;
//这个创建二叉树的函数是直接从“二叉树的二叉链表存储表示”复制过来的
Status CreateBiThrTree(BiThrTree *T)
{
char ch;
scanf("%c",&ch);
if(ch == ' ')
*T = NULL;
else
{
if(!(*T = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
(*T)->data = ch;
(*T)->LTag = Link;
(*T)->RTag = Link;
CreateBiThrTree(&(*T)->lchild); //构造左子树
CreateBiThrTree(&(*T)->rchild); //构造右子树
}
return OK;
}
void InThreading(BiThrTree p)
{
if(p)
{
InThreading(p->lchild); //左子树线索化
if(!p->lchild) //前驱线索
{
p->LTag = Thread;
p->lchild = pre;
}
if(!pre->rchild) //后继线索
{
pre->RTag = Thread;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild);
}
}
Status InOrderThreading(BiThrTree *Thrt, BiThrTree T)
{
if(!(*Thrt = (BiThrTree)malloc(sizeof(BiThrNode))))
exit(OVERFLOW);
(*Thrt)->LTag = Link;
(*Thrt)->RTag = Thread; //建头结点
(*Thrt)->rchild = *Thrt; //右指针回指
if(!T) //若二叉树空,则左指针回指
(*Thrt)->lchild = *Thrt;
else
{
(*Thrt)->lchild = T;
pre = *Thrt;
InThreading(T); //中序遍历进行中序线索化
pre->rchild = *Thrt; //最后一个结点线索化
pre->RTag = Thread;
(*Thrt)->rchild = pre;
}
return OK;
}
Status InOrderTraverse_Thr(BiThrTree T, Status (* Visit)(TElemType e))
{
BiThrTree p;
p = T->lchild;
while(p != T)
{
while(p->LTag == Link)
p = p->lchild;
if(!Visit(p->data))
return ERROR;
while(p->RTag==Thread && p->rchild !=T)
{
p = p->rchild;
Visit(p->data); //访问后继结点
}
p = p->rchild;
}
return OK;
}
/*
Status InOrder(BiTree T, Status (* Visit)(TElemType e))
{
SqStack s;
BiTree p = T;
InitStack(&s);
while(p!=NULL || !StackEmpty(&s)) //若当前结点p不空 或者 栈s不空,则执行循环体
{
while(p!=NULL) //若当前结点p不空
{
Push(&s, *p); //当前结点p进栈
p = p->lchild; //将p的左孩子置为当前结点p
}
if(!StackEmpty(&s)) //若栈s不空
{
//GetTop1(&s, &p); //这里没必要在调用GetTop来获得栈顶元素了,因为下面的Pop1就可以得到栈顶元素了。
Pop1(&s, &p); //进行出栈操作,获得栈顶元素并将其置为当前结点p
Visit(p->data); //访问当前结点的data。
p = p->rchild; //将p的右孩子置为当前结点p
}
}
return OK;
}
*/
main.c
//程序暂时还没看懂
#include "common.h"
#include "BiThrTree.h"
#include "stdio.h"
#include "stdlib.h"
Status PrintElement(TElemType e)
{
printf("%c ",e);
return OK;
}
int main()
{
BiThrNode *tree;
BiThrTree *thr;
CreateBiThrTree(&tree);
InOrderThreading(&thr, tree);
InOrderTraverse_Thr(tree, PrintElement);
return OK;
}
本工程编译无错有警告,警告内容如下:(第一个警告暂且可以忽略,但我不明白第2、3个警告是怎么回事)
但是本工程执行结果倒是正确的。
(最近有点忙,好久没看《数据结构》了,本工程的内容暂时还没看懂(等用到的时候再看吧),不过可以运行,执行结果是正确的)