前几天面试吃了一次瘪,笔试题让我非递归前序遍历,我毫不犹豫的就写了一个栈。然后利用压栈将前驱遍历迅速写了出来,当时喜滋滋的寻思今天的又比较顺利哈!
面试的时候,考官问我,能不能不用栈,不递归实现呢?我顿时呆了... ... 从来都没有思考过这个问题!直接影响了我后面的答题!
回来后翻阅资料,其实一颗线索二叉树很easy的解决了这个问题!这也说明了我对数据结构知识理解的不够深刻,没办法把实际问题与数据结构相结合!
那么今天就再预习一下线索树吧!
本文章文字是比较少的,线索化过程各种各样的数据结构书中都做了极为详细的解释,我的代码风格是模仿了Mark Allen的《数据结构与算法分析》中的风格!
这本书没有讲过线索二叉树的!
根据另一本书《数据结构》严老师版本里学习的线索化加上Mark的代码风格,就形成了本文,故以原创姿态发表不应该算是抄袭吧!
这个风格的代码易读性非常好,虽然我没有加一句注释,有基础的人看这些代码应该没有任何问题。
config.h:
#ifndef _CONFIG_H_
#define _CONFIG_H_
#include<stdio.h>
#include<stdlib.h>
#define OK 0
#define ERROR -1
#define TRUE 1
#define FALSE 0
#endif
BiTree.h
#ifndef _BITREE_H_
#define _BITREE_H_
#include "config.h"
typedef enum{Link,Thread}PointerTag;
typedef int ElemType;
typedef int Status;
typedef struct Node
{
ElemType data;
struct Node * lchild;
struct Node * rchild;
PointerTag lTag;
PointerTag rTag;
}BiThrNode,*BiThrTree;
Status visit(BiThrTree T);
BiThrTree Insert(BiThrTree T,ElemType e);
void PreThreading(BiThrTree T);
void PreOrderThreading(BiThrTree T,BiThrTree &H);
void PreOrderTraverse(BiThrTree H);
#endif
#include"BiTree.h"
Status visit(BiThrTree T)
{
if(T == NULL)
{
return FALSE;
}
printf("%d ",T->data);
return OK;
}
BiThrTree Insert(BiThrTree T,ElemType e)
{
if(T == NULL)
{
T = (BiThrTree)malloc(sizeof(BiThrNode));
if(T == NULL)
{
exit(ERROR);
}
T->lchild = NULL;
T->rchild = NULL;
T->lTag = Link;
T->rTag = Link;
T->data = e;
}
else
{
if (e<T->data)
{
T->lchild = Insert(T->lchild,e);
}
else
{
T->rchild = Insert(T->rchild,e);
}
}
return T;
}
BiThrTree Pre;
void PreThreading(BiThrTree T)
{
if (T == NULL)
{
return;
}
if(T->lchild == NULL)
{
T->lTag = Thread;
T->lchild = Pre;
}
if (Pre->rchild == NULL)
{
Pre->rTag = Thread;
Pre->rchild = T;
}
Pre = T;
if (T->lTag == Link)
{
PreThreading(T->lchild);
}
if(T->rTag == Link)
{
PreThreading(T->rchild);
}
}
void PreOrderThreading(BiThrTree T,BiThrTree &H)
{
H = (BiThrTree)malloc(sizeof(BiThrNode));
if(H == NULL)
{
exit(FALSE);
}
H->rchild = H;
H->rTag = Link;
if(T == NULL)
{
H->lchild = H;
H->lTag = Link;
}
else
{
Pre = H;
H->lchild = T;
H->lTag = Link;
PreThreading(T);
Pre->rchild = H;
Pre->rTag = Link;
H->rchild = Pre;
}
}
void PreOrderTraverse(BiThrTree H)
{
if(H->lchild != H)
{
BiThrTree T = H->lchild;
while(T != H)
{
visit(T);
if (T->lTag == Link)
{
T = T->lchild;
}
else
{
T = T->rchild;
}
}
}
}
main中测试,原本我将这颗线索树平衡化!但是由于代码量大,本文的主旨是线索化,main中就比较简陋的测试!望海涵!
测试结果: