树的抽象数据类型表示ADT
ADT Tree{数据对象D:D是具有相同特性的元素的集合数据关系R:若D为空集,则称为空树;若D仅含有一个数据元素,则R为空集,否则R={H},H是如下二元关系(1).在D中存在唯一称为根的数据元素root,它在关系H下无前驱;(2).若D-{root}!=φ,则存在D-{root}的一个划分D_1,D_2,...,D_m(m>0),对任意j!=k(1<=k<=j,k<=m)有D_j并D_k=φ,且对任意的i(1<=i<=m),唯一存在数据元素x_i属于D_i,有<root,x_i>属于H;(3).对应于D-{root}的划分,H-{<root,x_i>,...,<root,x_m>}有唯一的一个划分H_1,H_2,...,H_m(m>0)对任意j!=k(1<=j,k<=m)有H_j并H_k=φ,且对任意i(1<=i<=m),H_i是D_i上的二元关系,(D_i,{H_i})是一颗符合本定义的树,称为根root的子树。基本操作:InitTree(&T)操作结果:构造空树TDestroyTree(&T)初始条件:树T存在操作结果:销毁树TCreateTree(&T,definition)初始条件:definition给出树的定义操作结果:按definition构造树TTreeEmpty(T)初始条件:树T存在操作结果:若T为空树,则返回TURE,否则返回FALSRETreeDepth(T)初始条件:树T存在操作结果:返回T的深度Root(T)初始条件:树T存在操作结果:返回T的根Value(T,cur_e)初始条件:树T存在,cur_e是T的某个结点操作结果:返回cur_e的值Assign(T,cur_e,value)初始条件:树T存在,cur_e是T的某个结点操作结果:结点cur_e赋值尾valueParent(T,cur_e)初始条件:树T存在,cur_e是T的某个结点操作结果:若cur_e是T的非根结点,则返回他的双亲,否则函数值为"空"LeftChild(T,cur_e)初始条件:树T存在,cur_e是T的某个结点操作结果:若cur_e是T的非叶子结点,则返回他的最左孩子,否则函数值为"空"RightSibling(T,cur_e)初始条件:树T存在,cur_e是T的某个结点操作结果:若cur_e有右兄弟,则返回他的右兄弟,否则函数值为"空"InsertChild(&T,&p,i,c)初始条件:树T存在,p指向T中的某个结点,1<=i<=p所指的结点的度+1,非空树c与T不相交操作结果:插入c为T中p所指结点的第i棵子树DeleteChild(&T,&p,i)初始条件:树T存在,p指向T中的某个结点,1<=i<=p所指的结点的度操作结果:删除T中p所指结点的第i棵子树TraverseTree(T,Visit())初始条件:树T存在,Visit函数是对结点操作的应用函数操作结果:按某种次序对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。}ADT Tree
二叉树的抽象数据类型表示ADT
ADT BinaryTree{数据对象D:D是具有相同特性的元素的集合数据关系R:若D=φ,则R=φ,BinaryTree称为空树;若D!=φ,则R={H},H是如下二元关系(1).在D中存在唯一称为根的数据元素root,它在关系H下无前驱;(2).若D-{root}!=φ,则存在D-{root}={D_1,D_r}(m>0),且D_1并D_r=φ(3).若D_1!=φ,则D_1中存在唯一的元素x_1,<root,x_1>属于H,且在D_1上的关系H_1包含于H;若D_r!=φ,则D_r中存在唯一的元素x_r,<root,x_r>属于H,且在D_r上的关系H_r包含于H;H={<root,x_1>,<root,x_r>,H_1,H_r}(4).(D_1,{H_1})是一棵符合本定义的二叉树,称为根的左子树,(D_r,{H_r})是一棵符合本定义的二叉树,称为根的右子树。基本操作:InitBiTree(&T)操作结果:构造空二叉树TDestroyBiTree(&T)初始条件:二叉树T存在操作结果:销毁二叉树TCreateBiTree(&T,definition)初始条件:definition给出二叉树的定义操作结果:按definition构造二叉树TClerarBiTree(&T)初始条件:二叉树T存在操作结果:将二叉树T清为空树BiTreeEmpty(T)初始条件:二叉树T存在操作结果:若T为空二叉树,则返回TURE,否则返回FALSREBiTreeDepth(T)初始条件:二叉树T存在操作结果:返回二叉树T的深度Root(T)初始条件:二叉树T存在操作结果:返回二叉树T的根Value(T,e)初始条件:树T存在,e是T的某个结点操作结果:返回e的值Assign(T,e,value)初始条件:二叉树T存在,e是T的某个结点操作结果:结点e赋值尾valueParent(T,e)初始条件:二叉树T存在,e是T的某个结点操作结果:若e是T的非根结点,则返回他的双亲,否则函数值为"空"LeftChild(T,e)初始条件:二叉树T存在,e是T的某个结点操作结果:若e是T的非叶子结点,则返回他的最左孩子,否则函数值为"空"RightChild(T,e)初始条件:二叉树T存在,e是T的某个结点操作结果:若e是T的非叶子结点,则返回他的最右孩子,否则函数值为"空"LeftSibling(T,e)初始条件:二叉树T存在,e是T的某个结点操作结果:若e有右兄弟,则返回他的右兄弟,否则函数值为"空"RightSibling(T,e)初始条件:二叉树T存在,e是T的某个结点操作结果:若e有右兄弟,则返回他的右兄弟,否则函数值为"空"InsertChild(T,p,LLR,c)初始条件:二叉树T存在,p指向T中的某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树DeleteChild(T,p,LR)初始条件:二叉树T存在,p指向T中的某个结点,LR为0或1操作结果:根据LR为0或1,删除T中p所指结点的左或右子树PreTraverse(T,Visit())初始条件:二叉树T存在,Visit函数是对结点操作的应用函数操作结果:先序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。InTraverse(T,Visit())初始条件:二叉树T存在,Visit函数是对结点操作的应用函数操作结果:中序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。PostTraverse(T,Visit())初始条件:二叉树T存在,Visit函数是对结点操作的应用函数操作结果:后序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。LevelTraverse(T,Visit())初始条件:二叉树T存在,Visit函数是对结点操作的应用函数操作结果:层序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。}ADT BinaryTree
二叉树顺序结构实现
#include "stdio.h"#include "stdlib.h"#include "math.h"#include "time.h"/*** @brief* 二叉树顺序结构实现.c*/#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */#define MAX_TREE_SIZE 100 /* 二叉树的最大结点数 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int TElemType; /* 树结点的数据类型,目前暂定为整型 */typedef TElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点 */typedef struct{int level,order; /* 结点的层,本层序号(按满二叉树计算) */}Position;TElemType Nil=0; /* 设整型以0为空 */Status visit(TElemType c){printf("%d ",c);return OK;}/* 构造空二叉树T。因为T是固定数组,不会改变,故不需要& */Status InitBiTree(SqBiTree T){int i;for(i=0;i<MAX_TREE_SIZE;i++)T[i]=Nil; /* 初值为空 */return OK;}/* 按层序次序输入二叉树中结点的值(字符型或整型), 构造顺序存储的二叉树T */Status CreateBiTree(SqBiTree T){int i=0;printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:\n",MAX_TREE_SIZE);while(i<10){T[i]=i+1;if(i!=0&&T[(i+1)/2-1]==Nil&&T[i]!=Nil) /* 此结点(不空)无双亲且不是根 */{printf("出现无双亲的非根结点%d\n",T[i]);exit(ERROR);}i++;}while(i<MAX_TREE_SIZE){T[i]=Nil; /* 将空赋值给T的后面的结点 */i++;}return OK;}#define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 *//* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */Status BiTreeEmpty(SqBiTree T){if(T[0]==Nil) /* 根结点为空,则树空 */return TRUE;elsereturn FALSE;}/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */int BiTreeDepth(SqBiTree T){int i,j=-1;for(i=MAX_TREE_SIZE-1;i>=0;i--) /* 找到最后一个结点 */if(T[i]!=Nil)break;i++;doj++;while(i>=powl(2,j));/* 计算2的j次幂。 */return j;}/* 初始条件: 二叉树T存在 *//* 操作结果: 当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */Status Root(SqBiTree T,TElemType *e){if(BiTreeEmpty(T)) /* T空 */return ERROR;else{*e=T[0];return OK;}}/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */TElemType Value(SqBiTree T,Position e){return T[(int)powl(2,e.level-1)+e.order-2];}/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */Status Assign(SqBiTree T,Position e,TElemType value){int i=(int)powl(2,e.level-1)+e.order-2; /* 将层、本层序号转为矩阵的序号 */if(value!=Nil&&T[(i+1)/2-1]==Nil) /* 给叶子赋非空值但双亲为空 */return ERROR;else if(value==Nil&&(T[i*2+1]!=Nil||T[i*2+2]!=Nil)) /* 给双亲赋空值但有叶子(不空) */return ERROR;T[i]=value;return OK;}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */TElemType Parent(SqBiTree T,TElemType e){int i;if(T[0]==Nil) /* 空树 */return Nil;for(i=1;i<=MAX_TREE_SIZE-1;i++)if(T[i]==e) /* 找到e */return T[(i+1)/2-1];return Nil; /* 没找到e */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */TElemType LeftChild(SqBiTree T,TElemType e){int i;if(T[0]==Nil) /* 空树 */return Nil;for(i=0;i<=MAX_TREE_SIZE-1;i++)if(T[i]==e) /* 找到e */return T[i*2+1];return Nil; /* 没找到e */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */TElemType RightChild(SqBiTree T,TElemType e){int i;if(T[0]==Nil) /* 空树 */return Nil;for(i=0;i<=MAX_TREE_SIZE-1;i++)if(T[i]==e) /* 找到e */return T[i*2+2];return Nil; /* 没找到e */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */TElemType LeftSibling(SqBiTree T,TElemType e){int i;if(T[0]==Nil) /* 空树 */return Nil;for(i=1;i<=MAX_TREE_SIZE-1;i++)if(T[i]==e&&i%2==0) /* 找到e且其序号为偶数(是右孩子) */return T[i-1];return Nil; /* 没找到e */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */TElemType RightSibling(SqBiTree T,TElemType e){int i;if(T[0]==Nil) /* 空树 */return Nil;for(i=1;i<=MAX_TREE_SIZE-1;i++)if(T[i]==e&&i%2) /* 找到e且其序号为奇数(是左孩子) */return T[i+1];return Nil; /* 没找到e */}/* PreOrderTraverse()调用 */void PreTraverse(SqBiTree T,int e){visit(T[e]);if(T[2*e+1]!=Nil) /* 左子树不空 */PreTraverse(T,2*e+1);if(T[2*e+2]!=Nil) /* 右子树不空 */PreTraverse(T,2*e+2);}/* 初始条件: 二叉树存在 *//* 操作结果: 先序遍历T。 */Status PreOrderTraverse(SqBiTree T){if(!BiTreeEmpty(T)) /* 树不空 */PreTraverse(T,0);printf("\n");return OK;}/* InOrderTraverse()调用 */void InTraverse(SqBiTree T,int e){if(T[2*e+1]!=Nil) /* 左子树不空 */InTraverse(T,2*e+1);visit(T[e]);if(T[2*e+2]!=Nil) /* 右子树不空 */InTraverse(T,2*e+2);}/* 初始条件: 二叉树存在 *//* 操作结果: 中序遍历T。 */Status InOrderTraverse(SqBiTree T){if(!BiTreeEmpty(T)) /* 树不空 */InTraverse(T,0);printf("\n");return OK;}/* PostOrderTraverse()调用 */void PostTraverse(SqBiTree T,int e){if(T[2*e+1]!=Nil) /* 左子树不空 */PostTraverse(T,2*e+1);if(T[2*e+2]!=Nil) /* 右子树不空 */PostTraverse(T,2*e+2);visit(T[e]);}/* 初始条件: 二叉树T存在 *//* 操作结果: 后序遍历T。 */Status PostOrderTraverse(SqBiTree T){if(!BiTreeEmpty(T)) /* 树不空 */PostTraverse(T,0);printf("\n");return OK;}/* 层序遍历二叉树 */void LevelOrderTraverse(SqBiTree T){int i=MAX_TREE_SIZE-1,j;while(T[i]==Nil)i--; /* 找到最后一个非空结点的序号 */for(j=0;j<=i;j++) /* 从根结点起,按层序遍历二叉树 */if(T[j]!=Nil)visit(T[j]); /* 只遍历非空的结点 */printf("\n");}/* 逐层、按本层序号输出二叉树 */void Print(SqBiTree T){int j,k;Position p;TElemType e;for(j=1;j<=BiTreeDepth(T);j++){printf("第%d层: ",j);for(k=1;k<=powl(2,j-1);k++){p.level=j;p.order=k;e=Value(T,p);if(e!=Nil)printf("%d:%d ",k,e);}printf("\n");}}int main(){Status i;Position p;TElemType e;SqBiTree T;InitBiTree(T);CreateBiTree(T);printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));i=Root(T,&e);if(i)printf("二叉树的根为:%d\n",e);elseprintf("树空,无根\n");printf("层序遍历二叉树:\n");LevelOrderTraverse(T);printf("前序遍历二叉树:\n");PreOrderTraverse(T);printf("中序遍历二叉树:\n");InOrderTraverse(T);printf("后序遍历二叉树:\n");PostOrderTraverse(T);printf("修改结点的层号3本层序号2。");p.level=3;p.order=2;e=Value(T,p);printf("待修改结点的原值为%d请输入新值:50 ",e);e=50;Assign(T,p,e);printf("前序遍历二叉树:\n");PreOrderTraverse(T);printf("结点%d的双亲为%d,左右孩子分别为",e,Parent(T,e));printf("%d,%d,左右兄弟分别为",LeftChild(T,e),RightChild(T,e));printf("%d,%d\n",LeftSibling(T,e),RightSibling(T,e));ClearBiTree(T);printf("清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));i=Root(T,&e);if(i)printf("二叉树的根为:%d\n",e);elseprintf("树空,无根\n");return 0;}
测试输出
请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤100:建立二叉树后,树空否?0(1:是 0:否) 树的深度=4二叉树的根为:1层序遍历二叉树:1 2 3 4 5 6 7 8 9 10前序遍历二叉树:1 2 4 8 9 5 10 3 6 7中序遍历二叉树:8 4 9 2 10 5 1 6 3 7后序遍历二叉树:8 9 4 10 5 2 6 7 3 1修改结点的层号3本层序号2。待修改结点的原值为5请输入新值:50 前序遍历二叉树:1 2 4 8 9 50 10 3 6 7结点50的双亲为2,左右孩子分别为10,0,左右兄弟分别为4,0清除二叉树后,树空否?1(1:是 0:否) 树的深度=0树空,无根
二叉树链式结构实现
#include "string.h"#include "stdio.h"#include "stdlib.h"#include "math.h"#include "time.h"/*二叉树链式结构实现*/#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* 用于构造二叉树********************************** */int treeIndex=1;typedef char String[24]; /* 0号单元存放串的长度 */String str;Status StrAssign(String T,char *chars){int i;if(strlen(chars)>MAXSIZE)return ERROR;else{T[0]=strlen(chars);for(i=1;i<=T[0];i++)T[i]=*(chars+i-1);return OK;}}/* ************************************************ */typedef char TElemType;TElemType Nil=' '; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ",e);return OK;}typedef struct BiTNode /* 结点结构 */{TElemType data; /* 结点数据 */struct BiTNode *lchild,*rchild; /* 左右孩子指针 */}BiTNode,*BiTree;/* 构造空二叉树T */Status InitBiTree(BiTree *T){*T=NULL;return OK;}/* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */void DestroyBiTree(BiTree *T){if(*T){if((*T)->lchild) /* 有左孩子 */DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */if((*T)->rchild) /* 有右孩子 */DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */free(*T); /* 释放根结点 */*T=NULL; /* 空指针赋0 */}}/* 按前序输入二叉树中结点的值(一个字符) *//* #表示空树,构造二叉链表表示二叉树T。 */void CreateBiTree(BiTree *T){TElemType ch;/* scanf("%c",&ch); */ch=str[treeIndex++];if(ch=='#')*T=NULL;else{*T=(BiTree)malloc(sizeof(BiTNode));if(!*T)exit(OVERFLOW);(*T)->data=ch; /* 生成根结点 */CreateBiTree(&(*T)->lchild); /* 构造左子树 */CreateBiTree(&(*T)->rchild); /* 构造右子树 */}}/* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */Status BiTreeEmpty(BiTree T){if(T)return FALSE;elsereturn TRUE;}#define ClearBiTree DestroyBiTree/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */int BiTreeDepth(BiTree T){int i,j;if(!T)return 0;if(T->lchild)i=BiTreeDepth(T->lchild);elsei=0;if(T->rchild)j=BiTreeDepth(T->rchild);elsej=0;return i>j?i+1:j+1;}/* 初始条件: 二叉树T存在。操作结果: 返回T的根 */TElemType Root(BiTree T){if(BiTreeEmpty(T))return Nil;elsereturn T->data;}/* 初始条件: 二叉树T存在,p指向T中某个结点 *//* 操作结果: 返回p所指结点的值 */TElemType Value(BiTree p){return p->data;}/* 给p所指结点赋值为value */void Assign(BiTree p,TElemType value){p->data=value;}/* 初始条件: 二叉树T存在 *//* 操作结果: 前序递归遍历T */void PreOrderTraverse(BiTree T){if(T==NULL)return;printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */}/* 初始条件: 二叉树T存在 *//* 操作结果: 中序递归遍历T */void InOrderTraverse(BiTree T){if(T==NULL)return;InOrderTraverse(T->lchild); /* 中序遍历左子树 */printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */}/* 初始条件: 二叉树T存在 *//* 操作结果: 后序递归遍历T */void PostOrderTraverse(BiTree T){if(T==NULL)return;PostOrderTraverse(T->lchild); /* 先后序遍历左子树 */PostOrderTraverse(T->rchild); /* 再后序遍历右子树 */printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */}int main(){int i;BiTree T;TElemType e1;InitBiTree(&T);StrAssign(str,"ABDH#K###E##CFI###G#J##");CreateBiTree(&T);printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));e1=Root(T);printf("二叉树的根为: %c\n",e1);printf("\n前序遍历二叉树:");PreOrderTraverse(T);printf("\n中序遍历二叉树:");InOrderTraverse(T);printf("\n后序遍历二叉树:");PostOrderTraverse(T);ClearBiTree(&T);printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));i=Root(T);if(!i)printf("树空,无根\n");return 0;}
测试输出
构造空二叉树后,树空否?0(1:是 0:否) 树的深度=5二叉树的根为: A前序遍历二叉树:ABDHKECFIGJ中序遍历二叉树:HKDBEAIFCGJ后序遍历二叉树:KHDEBIFJGCA清除二叉树后,树空否?1(1:是 0:否) 树的深度=0
线索二叉树
#include "string.h"#include "stdio.h"#include "stdlib.h"#include "math.h"#include "time.h"/*** @brief* 线索二叉树*/#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef char TElemType;typedef enum {Link,Thread} PointerTag; /* Link=0表示指向左右孩子指针, *//* Thread=1表示指向前驱或后继的线索 */typedef struct BiThrNode /* 二叉线索存储结点结构 */{TElemType data; /* 结点数据 */struct BiThrNode *lchild, *rchild; /* 左右孩子指针 */PointerTag LTag;PointerTag RTag; /* 左右标志 */} BiThrNode, *BiThrTree;TElemType Nil='#'; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ",e);return OK;}/* 按前序输入二叉线索树中结点的值,构造二叉线索树T *//* 0(整型)/空格(字符型)表示空结点 */Status CreateBiThrTree(BiThrTree *T){TElemType h;scanf("%c",&h);if(h==Nil)*T=NULL;else{*T=(BiThrTree)malloc(sizeof(BiThrNode));if(!*T)exit(OVERFLOW);(*T)->data=h; /* 生成根结点(前序) */CreateBiThrTree(&(*T)->lchild); /* 递归构造左子树 */if((*T)->lchild) /* 有左孩子 */(*T)->LTag=Link;CreateBiThrTree(&(*T)->rchild); /* 递归构造右子树 */if((*T)->rchild) /* 有右孩子 */(*T)->RTag=Link;}return OK;}BiThrTree pre; /* 全局变量,始终指向刚刚访问过的结点 *//* 中序遍历进行中序线索化 */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; /* 前驱右孩子指针指向后继(当前结点p) */}pre=p; /* 保持pre指向p的前驱 */InThreading(p->rchild); /* 递归右子树线索化 */}}/* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 */Status InOrderThreading(BiThrTree *Thrt,BiThrTree T){*Thrt=(BiThrTree)malloc(sizeof(BiThrNode));if(!*Thrt)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;}/* 中序遍历二叉线索树T(头结点)的非递归算法 */Status InOrderTraverse_Thr(BiThrTree T){BiThrTree p;p=T->lchild; /* p指向根结点 */while(p!=T){ /* 空树或遍历结束时,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;}int main(){BiThrTree H,T;printf("请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')\n");CreateBiThrTree(&T); /* 按前序产生二叉树 */InOrderThreading(&H,T); /* 中序遍历,并中序线索化二叉树 */printf("中序遍历(输出)二叉线索树:\n");InOrderTraverse_Thr(H); /* 中序遍历(输出)二叉线索树 */printf("\n");return 0;}
测试输出
请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')ABDH##I##EJ###CF##G##中序遍历(输出)二叉线索树:H D I B J E A F C G
