树的抽象数据类型表示ADT

  1. ADT Tree{
  2. 数据对象DD是具有相同特性的元素的集合
  3. 数据关系R:若D为空集,则称为空树;若D仅含有一个数据元素,则R为空集,否则R={H},H是如下二元关系
  4. (1).在D中存在唯一称为根的数据元素root,它在关系H下无前驱;
  5. (2).若D-{root}!=φ,则存在D-{root}的一个划分D_1,D_2,...,D_m(m>0),对任意j!=k
  6. (1<=k<=j,k<=m)有D_jD_k=φ,且对任意的i(1<=i<=m),唯一存在数据元素x_i属于D_i,有<root,x_i>属于H
  7. (3).对应于D-{root}的划分,H-{<root,x_i>,...,<root,x_m>}有唯一的一个划分H_1,H_2,...,H_m(m>0)
  8. 对任意j!=k(1<=j,k<=m)有H_jH_k=φ,且对任意i(1<=i<=m),H_iD_i上的二元关系,(D_i,{H_i})是一颗符合本定义的树,称为根root的子树。
  9. 基本操作:
  10. InitTree(&T)
  11. 操作结果:构造空树T
  12. DestroyTree(&T)
  13. 初始条件:树T存在
  14. 操作结果:销毁树T
  15. CreateTree(&T,definition)
  16. 初始条件:definition给出树的定义
  17. 操作结果:按definition构造树T
  18. TreeEmpty(T)
  19. 初始条件:树T存在
  20. 操作结果:若T为空树,则返回TURE,否则返回FALSRE
  21. TreeDepth(T)
  22. 初始条件:树T存在
  23. 操作结果:返回T的深度
  24. Root(T)
  25. 初始条件:树T存在
  26. 操作结果:返回T的根
  27. Value(T,cur_e)
  28. 初始条件:树T存在,cur_eT的某个结点
  29. 操作结果:返回cur_e的值
  30. Assign(T,cur_e,value)
  31. 初始条件:树T存在,cur_eT的某个结点
  32. 操作结果:结点cur_e赋值尾value
  33. Parent(T,cur_e)
  34. 初始条件:树T存在,cur_eT的某个结点
  35. 操作结果:若cur_eT的非根结点,则返回他的双亲,否则函数值为"空"
  36. LeftChild(T,cur_e)
  37. 初始条件:树T存在,cur_eT的某个结点
  38. 操作结果:若cur_eT的非叶子结点,则返回他的最左孩子,否则函数值为"空"
  39. RightSibling(T,cur_e)
  40. 初始条件:树T存在,cur_eT的某个结点
  41. 操作结果:若cur_e有右兄弟,则返回他的右兄弟,否则函数值为"空"
  42. InsertChild(&T,&p,i,c)
  43. 初始条件:树T存在,p指向T中的某个结点,1<=i<=p所指的结点的度+1,非空树cT不相交
  44. 操作结果:插入cTp所指结点的第i棵子树
  45. DeleteChild(&T,&p,i)
  46. 初始条件:树T存在,p指向T中的某个结点,1<=i<=p所指的结点的度
  47. 操作结果:删除Tp所指结点的第i棵子树
  48. TraverseTree(T,Visit())
  49. 初始条件:树T存在,Visit函数是对结点操作的应用函数
  50. 操作结果:按某种次序对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。
  51. }ADT Tree

二叉树的抽象数据类型表示ADT

  1. ADT BinaryTree{
  2. 数据对象DD是具有相同特性的元素的集合
  3. 数据关系R
  4. D=φ,则R=φ,BinaryTree称为空树;
  5. D!=φ,则R={H},H是如下二元关系
  6. (1).在D中存在唯一称为根的数据元素root,它在关系H下无前驱;
  7. (2).若D-{root}!=φ,则存在D-{root}={D_1,D_r}(m>0),且D_1D_r
  8. (3).若D_1!=φ,则D_1中存在唯一的元素x_1,<root,x_1>属于H,且在D_1上的关系H_1包含于H;若
  9. D_r!=φ,则D_r中存在唯一的元素x_r,<root,x_r>属于H,且在D_r上的关系H_r包含于HH={<root,x_1>,<root,x_r>,H_1,H_r}
  10. (4).(D_1,{H_1})是一棵符合本定义的二叉树,称为根的左子树,(D_r,{H_r})是一棵符合本定义的二叉树,称为根的右子树。
  11. 基本操作:
  12. InitBiTree(&T)
  13. 操作结果:构造空二叉树T
  14. DestroyBiTree(&T)
  15. 初始条件:二叉树T存在
  16. 操作结果:销毁二叉树T
  17. CreateBiTree(&T,definition)
  18. 初始条件:definition给出二叉树的定义
  19. 操作结果:按definition构造二叉树T
  20. ClerarBiTree(&T)
  21. 初始条件:二叉树T存在
  22. 操作结果:将二叉树T清为空树
  23. BiTreeEmpty(T)
  24. 初始条件:二叉树T存在
  25. 操作结果:若T为空二叉树,则返回TURE,否则返回FALSRE
  26. BiTreeDepth(T)
  27. 初始条件:二叉树T存在
  28. 操作结果:返回二叉树T的深度
  29. Root(T)
  30. 初始条件:二叉树T存在
  31. 操作结果:返回二叉树T的根
  32. Value(T,e)
  33. 初始条件:树T存在,eT的某个结点
  34. 操作结果:返回e的值
  35. Assign(T,e,value)
  36. 初始条件:二叉树T存在,eT的某个结点
  37. 操作结果:结点e赋值尾value
  38. Parent(T,e)
  39. 初始条件:二叉树T存在,eT的某个结点
  40. 操作结果:若eT的非根结点,则返回他的双亲,否则函数值为"空"
  41. LeftChild(T,e)
  42. 初始条件:二叉树T存在,eT的某个结点
  43. 操作结果:若eT的非叶子结点,则返回他的最左孩子,否则函数值为"空"
  44. RightChild(T,e)
  45. 初始条件:二叉树T存在,eT的某个结点
  46. 操作结果:若eT的非叶子结点,则返回他的最右孩子,否则函数值为"空"
  47. LeftSibling(T,e)
  48. 初始条件:二叉树T存在,eT的某个结点
  49. 操作结果:若e有右兄弟,则返回他的右兄弟,否则函数值为"空"
  50. RightSibling(T,e)
  51. 初始条件:二叉树T存在,eT的某个结点
  52. 操作结果:若e有右兄弟,则返回他的右兄弟,否则函数值为"空"
  53. InsertChild(T,p,LLR,c)
  54. 初始条件:二叉树T存在,p指向T中的某个结点,LR01,非空二叉树cT不相交且右子树为空
  55. 操作结果:根据LR01,插入cTp所指结点的左或右子树
  56. DeleteChild(T,p,LR)
  57. 初始条件:二叉树T存在,p指向T中的某个结点,LR01
  58. 操作结果:根据LR01,删除Tp所指结点的左或右子树
  59. PreTraverse(T,Visit())
  60. 初始条件:二叉树T存在,Visit函数是对结点操作的应用函数
  61. 操作结果:先序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。
  62. InTraverse(T,Visit())
  63. 初始条件:二叉树T存在,Visit函数是对结点操作的应用函数
  64. 操作结果:中序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。
  65. PostTraverse(T,Visit())
  66. 初始条件:二叉树T存在,Visit函数是对结点操作的应用函数
  67. 操作结果:后序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。
  68. LevelTraverse(T,Visit())
  69. 初始条件:二叉树T存在,Visit函数是对结点操作的应用函数
  70. 操作结果:层序遍历T,对T的每个结点调用函数Visit()一次且至多一次,一旦Visit()失败,则操作失败。
  71. }ADT BinaryTree

二叉树顺序结构实现

  1. #include "stdio.h"
  2. #include "stdlib.h"
  3. #include "math.h"
  4. #include "time.h"
  5. /**
  6. * @brief
  7. * 二叉树顺序结构实现.c
  8. */
  9. #define OK 1
  10. #define ERROR 0
  11. #define TRUE 1
  12. #define FALSE 0
  13. #define MAXSIZE 100 /* 存储空间初始分配量 */
  14. #define MAX_TREE_SIZE 100 /* 二叉树的最大结点数 */
  15. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  16. typedef int TElemType; /* 树结点的数据类型,目前暂定为整型 */
  17. typedef TElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点 */
  18. typedef struct
  19. {
  20. int level,order; /* 结点的层,本层序号(按满二叉树计算) */
  21. }Position;
  22. TElemType Nil=0; /* 设整型以0为空 */
  23. Status visit(TElemType c)
  24. {
  25. printf("%d ",c);
  26. return OK;
  27. }
  28. /* 构造空二叉树T。因为T是固定数组,不会改变,故不需要& */
  29. Status InitBiTree(SqBiTree T)
  30. {
  31. int i;
  32. for(i=0;i<MAX_TREE_SIZE;i++)
  33. T[i]=Nil; /* 初值为空 */
  34. return OK;
  35. }
  36. /* 按层序次序输入二叉树中结点的值(字符型或整型), 构造顺序存储的二叉树T */
  37. Status CreateBiTree(SqBiTree T)
  38. {
  39. int i=0;
  40. printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:\n",MAX_TREE_SIZE);
  41. while(i<10)
  42. {
  43. T[i]=i+1;
  44. if(i!=0&&T[(i+1)/2-1]==Nil&&T[i]!=Nil) /* 此结点(不空)无双亲且不是根 */
  45. {
  46. printf("出现无双亲的非根结点%d\n",T[i]);
  47. exit(ERROR);
  48. }
  49. i++;
  50. }
  51. while(i<MAX_TREE_SIZE)
  52. {
  53. T[i]=Nil; /* 将空赋值给T的后面的结点 */
  54. i++;
  55. }
  56. return OK;
  57. }
  58. #define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 */
  59. /* 初始条件: 二叉树T存在 */
  60. /* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */
  61. Status BiTreeEmpty(SqBiTree T)
  62. {
  63. if(T[0]==Nil) /* 根结点为空,则树空 */
  64. return TRUE;
  65. else
  66. return FALSE;
  67. }
  68. /* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */
  69. int BiTreeDepth(SqBiTree T)
  70. {
  71. int i,j=-1;
  72. for(i=MAX_TREE_SIZE-1;i>=0;i--) /* 找到最后一个结点 */
  73. if(T[i]!=Nil)
  74. break;
  75. i++;
  76. do
  77. j++;
  78. while(i>=powl(2,j));/* 计算2的j次幂。 */
  79. return j;
  80. }
  81. /* 初始条件: 二叉树T存在 */
  82. /* 操作结果: 当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */
  83. Status Root(SqBiTree T,TElemType *e)
  84. {
  85. if(BiTreeEmpty(T)) /* T空 */
  86. return ERROR;
  87. else
  88. {
  89. *e=T[0];
  90. return OK;
  91. }
  92. }
  93. /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
  94. /* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */
  95. TElemType Value(SqBiTree T,Position e)
  96. {
  97. return T[(int)powl(2,e.level-1)+e.order-2];
  98. }
  99. /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) */
  100. /* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */
  101. Status Assign(SqBiTree T,Position e,TElemType value)
  102. {
  103. int i=(int)powl(2,e.level-1)+e.order-2; /* 将层、本层序号转为矩阵的序号 */
  104. if(value!=Nil&&T[(i+1)/2-1]==Nil) /* 给叶子赋非空值但双亲为空 */
  105. return ERROR;
  106. else if(value==Nil&&(T[i*2+1]!=Nil||T[i*2+2]!=Nil)) /* 给双亲赋空值但有叶子(不空) */
  107. return ERROR;
  108. T[i]=value;
  109. return OK;
  110. }
  111. /* 初始条件: 二叉树T存在,e是T中某个结点 */
  112. /* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */
  113. TElemType Parent(SqBiTree T,TElemType e)
  114. {
  115. int i;
  116. if(T[0]==Nil) /* 空树 */
  117. return Nil;
  118. for(i=1;i<=MAX_TREE_SIZE-1;i++)
  119. if(T[i]==e) /* 找到e */
  120. return T[(i+1)/2-1];
  121. return Nil; /* 没找到e */
  122. }
  123. /* 初始条件: 二叉树T存在,e是T中某个结点 */
  124. /* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */
  125. TElemType LeftChild(SqBiTree T,TElemType e)
  126. {
  127. int i;
  128. if(T[0]==Nil) /* 空树 */
  129. return Nil;
  130. for(i=0;i<=MAX_TREE_SIZE-1;i++)
  131. if(T[i]==e) /* 找到e */
  132. return T[i*2+1];
  133. return Nil; /* 没找到e */
  134. }
  135. /* 初始条件: 二叉树T存在,e是T中某个结点 */
  136. /* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */
  137. TElemType RightChild(SqBiTree T,TElemType e)
  138. {
  139. int i;
  140. if(T[0]==Nil) /* 空树 */
  141. return Nil;
  142. for(i=0;i<=MAX_TREE_SIZE-1;i++)
  143. if(T[i]==e) /* 找到e */
  144. return T[i*2+2];
  145. return Nil; /* 没找到e */
  146. }
  147. /* 初始条件: 二叉树T存在,e是T中某个结点 */
  148. /* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */
  149. TElemType LeftSibling(SqBiTree T,TElemType e)
  150. {
  151. int i;
  152. if(T[0]==Nil) /* 空树 */
  153. return Nil;
  154. for(i=1;i<=MAX_TREE_SIZE-1;i++)
  155. if(T[i]==e&&i%2==0) /* 找到e且其序号为偶数(是右孩子) */
  156. return T[i-1];
  157. return Nil; /* 没找到e */
  158. }
  159. /* 初始条件: 二叉树T存在,e是T中某个结点 */
  160. /* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */
  161. TElemType RightSibling(SqBiTree T,TElemType e)
  162. {
  163. int i;
  164. if(T[0]==Nil) /* 空树 */
  165. return Nil;
  166. for(i=1;i<=MAX_TREE_SIZE-1;i++)
  167. if(T[i]==e&&i%2) /* 找到e且其序号为奇数(是左孩子) */
  168. return T[i+1];
  169. return Nil; /* 没找到e */
  170. }
  171. /* PreOrderTraverse()调用 */
  172. void PreTraverse(SqBiTree T,int e)
  173. {
  174. visit(T[e]);
  175. if(T[2*e+1]!=Nil) /* 左子树不空 */
  176. PreTraverse(T,2*e+1);
  177. if(T[2*e+2]!=Nil) /* 右子树不空 */
  178. PreTraverse(T,2*e+2);
  179. }
  180. /* 初始条件: 二叉树存在 */
  181. /* 操作结果: 先序遍历T。 */
  182. Status PreOrderTraverse(SqBiTree T)
  183. {
  184. if(!BiTreeEmpty(T)) /* 树不空 */
  185. PreTraverse(T,0);
  186. printf("\n");
  187. return OK;
  188. }
  189. /* InOrderTraverse()调用 */
  190. void InTraverse(SqBiTree T,int e)
  191. {
  192. if(T[2*e+1]!=Nil) /* 左子树不空 */
  193. InTraverse(T,2*e+1);
  194. visit(T[e]);
  195. if(T[2*e+2]!=Nil) /* 右子树不空 */
  196. InTraverse(T,2*e+2);
  197. }
  198. /* 初始条件: 二叉树存在 */
  199. /* 操作结果: 中序遍历T。 */
  200. Status InOrderTraverse(SqBiTree T)
  201. {
  202. if(!BiTreeEmpty(T)) /* 树不空 */
  203. InTraverse(T,0);
  204. printf("\n");
  205. return OK;
  206. }
  207. /* PostOrderTraverse()调用 */
  208. void PostTraverse(SqBiTree T,int e)
  209. {
  210. if(T[2*e+1]!=Nil) /* 左子树不空 */
  211. PostTraverse(T,2*e+1);
  212. if(T[2*e+2]!=Nil) /* 右子树不空 */
  213. PostTraverse(T,2*e+2);
  214. visit(T[e]);
  215. }
  216. /* 初始条件: 二叉树T存在 */
  217. /* 操作结果: 后序遍历T。 */
  218. Status PostOrderTraverse(SqBiTree T)
  219. {
  220. if(!BiTreeEmpty(T)) /* 树不空 */
  221. PostTraverse(T,0);
  222. printf("\n");
  223. return OK;
  224. }
  225. /* 层序遍历二叉树 */
  226. void LevelOrderTraverse(SqBiTree T)
  227. {
  228. int i=MAX_TREE_SIZE-1,j;
  229. while(T[i]==Nil)
  230. i--; /* 找到最后一个非空结点的序号 */
  231. for(j=0;j<=i;j++) /* 从根结点起,按层序遍历二叉树 */
  232. if(T[j]!=Nil)
  233. visit(T[j]); /* 只遍历非空的结点 */
  234. printf("\n");
  235. }
  236. /* 逐层、按本层序号输出二叉树 */
  237. void Print(SqBiTree T)
  238. {
  239. int j,k;
  240. Position p;
  241. TElemType e;
  242. for(j=1;j<=BiTreeDepth(T);j++)
  243. {
  244. printf("第%d层: ",j);
  245. for(k=1;k<=powl(2,j-1);k++)
  246. {
  247. p.level=j;
  248. p.order=k;
  249. e=Value(T,p);
  250. if(e!=Nil)
  251. printf("%d:%d ",k,e);
  252. }
  253. printf("\n");
  254. }
  255. }
  256. int main()
  257. {
  258. Status i;
  259. Position p;
  260. TElemType e;
  261. SqBiTree T;
  262. InitBiTree(T);
  263. CreateBiTree(T);
  264. printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
  265. i=Root(T,&e);
  266. if(i)
  267. printf("二叉树的根为:%d\n",e);
  268. else
  269. printf("树空,无根\n");
  270. printf("层序遍历二叉树:\n");
  271. LevelOrderTraverse(T);
  272. printf("前序遍历二叉树:\n");
  273. PreOrderTraverse(T);
  274. printf("中序遍历二叉树:\n");
  275. InOrderTraverse(T);
  276. printf("后序遍历二叉树:\n");
  277. PostOrderTraverse(T);
  278. printf("修改结点的层号3本层序号2。");
  279. p.level=3;
  280. p.order=2;
  281. e=Value(T,p);
  282. printf("待修改结点的原值为%d请输入新值:50 ",e);
  283. e=50;
  284. Assign(T,p,e);
  285. printf("前序遍历二叉树:\n");
  286. PreOrderTraverse(T);
  287. printf("结点%d的双亲为%d,左右孩子分别为",e,Parent(T,e));
  288. printf("%d,%d,左右兄弟分别为",LeftChild(T,e),RightChild(T,e));
  289. printf("%d,%d\n",LeftSibling(T,e),RightSibling(T,e));
  290. ClearBiTree(T);
  291. printf("清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
  292. i=Root(T,&e);
  293. if(i)
  294. printf("二叉树的根为:%d\n",e);
  295. else
  296. printf("树空,无根\n");
  297. return 0;
  298. }

测试输出

  1. 请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤100:
  2. 建立二叉树后,树空否?0(1:是 0:否) 树的深度=4
  3. 二叉树的根为:1
  4. 层序遍历二叉树:
  5. 1 2 3 4 5 6 7 8 9 10
  6. 前序遍历二叉树:
  7. 1 2 4 8 9 5 10 3 6 7
  8. 中序遍历二叉树:
  9. 8 4 9 2 10 5 1 6 3 7
  10. 后序遍历二叉树:
  11. 8 9 4 10 5 2 6 7 3 1
  12. 修改结点的层号3本层序号2。待修改结点的原值为5请输入新值:50 前序遍历二叉树:
  13. 1 2 4 8 9 50 10 3 6 7
  14. 结点50的双亲为2,左右孩子分别为10,0,左右兄弟分别为4,0
  15. 清除二叉树后,树空否?1(1:是 0:否) 树的深度=0
  16. 树空,无根

二叉树链式结构实现

  1. #include "string.h"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "math.h"
  5. #include "time.h"
  6. /*
  7. 二叉树链式结构实现
  8. */
  9. #define OK 1
  10. #define ERROR 0
  11. #define TRUE 1
  12. #define FALSE 0
  13. #define MAXSIZE 100 /* 存储空间初始分配量 */
  14. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  15. /* 用于构造二叉树********************************** */
  16. int treeIndex=1;
  17. typedef char String[24]; /* 0号单元存放串的长度 */
  18. String str;
  19. Status StrAssign(String T,char *chars)
  20. {
  21. int i;
  22. if(strlen(chars)>MAXSIZE)
  23. return ERROR;
  24. else
  25. {
  26. T[0]=strlen(chars);
  27. for(i=1;i<=T[0];i++)
  28. T[i]=*(chars+i-1);
  29. return OK;
  30. }
  31. }
  32. /* ************************************************ */
  33. typedef char TElemType;
  34. TElemType Nil=' '; /* 字符型以空格符为空 */
  35. Status visit(TElemType e)
  36. {
  37. printf("%c ",e);
  38. return OK;
  39. }
  40. typedef struct BiTNode /* 结点结构 */
  41. {
  42. TElemType data; /* 结点数据 */
  43. struct BiTNode *lchild,*rchild; /* 左右孩子指针 */
  44. }BiTNode,*BiTree;
  45. /* 构造空二叉树T */
  46. Status InitBiTree(BiTree *T)
  47. {
  48. *T=NULL;
  49. return OK;
  50. }
  51. /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */
  52. void DestroyBiTree(BiTree *T)
  53. {
  54. if(*T)
  55. {
  56. if((*T)->lchild) /* 有左孩子 */
  57. DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */
  58. if((*T)->rchild) /* 有右孩子 */
  59. DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */
  60. free(*T); /* 释放根结点 */
  61. *T=NULL; /* 空指针赋0 */
  62. }
  63. }
  64. /* 按前序输入二叉树中结点的值(一个字符) */
  65. /* #表示空树,构造二叉链表表示二叉树T。 */
  66. void CreateBiTree(BiTree *T)
  67. {
  68. TElemType ch;
  69. /* scanf("%c",&ch); */
  70. ch=str[treeIndex++];
  71. if(ch=='#')
  72. *T=NULL;
  73. else
  74. {
  75. *T=(BiTree)malloc(sizeof(BiTNode));
  76. if(!*T)
  77. exit(OVERFLOW);
  78. (*T)->data=ch; /* 生成根结点 */
  79. CreateBiTree(&(*T)->lchild); /* 构造左子树 */
  80. CreateBiTree(&(*T)->rchild); /* 构造右子树 */
  81. }
  82. }
  83. /* 初始条件: 二叉树T存在 */
  84. /* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */
  85. Status BiTreeEmpty(BiTree T)
  86. {
  87. if(T)
  88. return FALSE;
  89. else
  90. return TRUE;
  91. }
  92. #define ClearBiTree DestroyBiTree
  93. /* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */
  94. int BiTreeDepth(BiTree T)
  95. {
  96. int i,j;
  97. if(!T)
  98. return 0;
  99. if(T->lchild)
  100. i=BiTreeDepth(T->lchild);
  101. else
  102. i=0;
  103. if(T->rchild)
  104. j=BiTreeDepth(T->rchild);
  105. else
  106. j=0;
  107. return i>j?i+1:j+1;
  108. }
  109. /* 初始条件: 二叉树T存在。操作结果: 返回T的根 */
  110. TElemType Root(BiTree T)
  111. {
  112. if(BiTreeEmpty(T))
  113. return Nil;
  114. else
  115. return T->data;
  116. }
  117. /* 初始条件: 二叉树T存在,p指向T中某个结点 */
  118. /* 操作结果: 返回p所指结点的值 */
  119. TElemType Value(BiTree p)
  120. {
  121. return p->data;
  122. }
  123. /* 给p所指结点赋值为value */
  124. void Assign(BiTree p,TElemType value)
  125. {
  126. p->data=value;
  127. }
  128. /* 初始条件: 二叉树T存在 */
  129. /* 操作结果: 前序递归遍历T */
  130. void PreOrderTraverse(BiTree T)
  131. {
  132. if(T==NULL)
  133. return;
  134. printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
  135. PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */
  136. PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */
  137. }
  138. /* 初始条件: 二叉树T存在 */
  139. /* 操作结果: 中序递归遍历T */
  140. void InOrderTraverse(BiTree T)
  141. {
  142. if(T==NULL)
  143. return;
  144. InOrderTraverse(T->lchild); /* 中序遍历左子树 */
  145. printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
  146. InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */
  147. }
  148. /* 初始条件: 二叉树T存在 */
  149. /* 操作结果: 后序递归遍历T */
  150. void PostOrderTraverse(BiTree T)
  151. {
  152. if(T==NULL)
  153. return;
  154. PostOrderTraverse(T->lchild); /* 先后序遍历左子树 */
  155. PostOrderTraverse(T->rchild); /* 再后序遍历右子树 */
  156. printf("%c",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
  157. }
  158. int main()
  159. {
  160. int i;
  161. BiTree T;
  162. TElemType e1;
  163. InitBiTree(&T);
  164. StrAssign(str,"ABDH#K###E##CFI###G#J##");
  165. CreateBiTree(&T);
  166. printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
  167. e1=Root(T);
  168. printf("二叉树的根为: %c\n",e1);
  169. printf("\n前序遍历二叉树:");
  170. PreOrderTraverse(T);
  171. printf("\n中序遍历二叉树:");
  172. InOrderTraverse(T);
  173. printf("\n后序遍历二叉树:");
  174. PostOrderTraverse(T);
  175. ClearBiTree(&T);
  176. printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T));
  177. i=Root(T);
  178. if(!i)
  179. printf("树空,无根\n");
  180. return 0;
  181. }

测试输出

  1. 构造空二叉树后,树空否?0(1:是 0:否) 树的深度=5
  2. 二叉树的根为: A
  3. 前序遍历二叉树:ABDHKECFIGJ
  4. 中序遍历二叉树:HKDBEAIFCGJ
  5. 后序遍历二叉树:KHDEBIFJGCA
  6. 清除二叉树后,树空否?1(1:是 0:否) 树的深度=0

线索二叉树

  1. #include "string.h"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "math.h"
  5. #include "time.h"
  6. /**
  7. * @brief
  8. * 线索二叉树
  9. */
  10. #define OK 1
  11. #define ERROR 0
  12. #define TRUE 1
  13. #define FALSE 0
  14. #define MAXSIZE 100 /* 存储空间初始分配量 */
  15. typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
  16. typedef char TElemType;
  17. typedef enum {Link,Thread} PointerTag; /* Link=0表示指向左右孩子指针, */
  18. /* Thread=1表示指向前驱或后继的线索 */
  19. typedef struct BiThrNode /* 二叉线索存储结点结构 */
  20. {
  21. TElemType data; /* 结点数据 */
  22. struct BiThrNode *lchild, *rchild; /* 左右孩子指针 */
  23. PointerTag LTag;
  24. PointerTag RTag; /* 左右标志 */
  25. } BiThrNode, *BiThrTree;
  26. TElemType Nil='#'; /* 字符型以空格符为空 */
  27. Status visit(TElemType e)
  28. {
  29. printf("%c ",e);
  30. return OK;
  31. }
  32. /* 按前序输入二叉线索树中结点的值,构造二叉线索树T */
  33. /* 0(整型)/空格(字符型)表示空结点 */
  34. Status CreateBiThrTree(BiThrTree *T)
  35. {
  36. TElemType h;
  37. scanf("%c",&h);
  38. if(h==Nil)
  39. *T=NULL;
  40. else
  41. {
  42. *T=(BiThrTree)malloc(sizeof(BiThrNode));
  43. if(!*T)
  44. exit(OVERFLOW);
  45. (*T)->data=h; /* 生成根结点(前序) */
  46. CreateBiThrTree(&(*T)->lchild); /* 递归构造左子树 */
  47. if((*T)->lchild) /* 有左孩子 */
  48. (*T)->LTag=Link;
  49. CreateBiThrTree(&(*T)->rchild); /* 递归构造右子树 */
  50. if((*T)->rchild) /* 有右孩子 */
  51. (*T)->RTag=Link;
  52. }
  53. return OK;
  54. }
  55. BiThrTree pre; /* 全局变量,始终指向刚刚访问过的结点 */
  56. /* 中序遍历进行中序线索化 */
  57. void InThreading(BiThrTree p)
  58. {
  59. if(p)
  60. {
  61. InThreading(p->lchild); /* 递归左子树线索化 */
  62. if(!p->lchild) /* 没有左孩子 */
  63. {
  64. p->LTag=Thread; /* 前驱线索 */
  65. p->lchild=pre; /* 左孩子指针指向前驱 */
  66. }
  67. if(!pre->rchild) /* 前驱没有右孩子 */
  68. {
  69. pre->RTag=Thread; /* 后继线索 */
  70. pre->rchild=p; /* 前驱右孩子指针指向后继(当前结点p) */
  71. }
  72. pre=p; /* 保持pre指向p的前驱 */
  73. InThreading(p->rchild); /* 递归右子树线索化 */
  74. }
  75. }
  76. /* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 */
  77. Status InOrderThreading(BiThrTree *Thrt,BiThrTree T)
  78. {
  79. *Thrt=(BiThrTree)malloc(sizeof(BiThrNode));
  80. if(!*Thrt)
  81. exit(OVERFLOW);
  82. (*Thrt)->LTag=Link; /* 建头结点 */
  83. (*Thrt)->RTag=Thread;
  84. (*Thrt)->rchild=(*Thrt); /* 右指针回指 */
  85. if(!T) /* 若二叉树空,则左指针回指 */
  86. (*Thrt)->lchild=*Thrt;
  87. else
  88. {
  89. (*Thrt)->lchild=T;
  90. pre=(*Thrt);
  91. InThreading(T); /* 中序遍历进行中序线索化 */
  92. pre->rchild=*Thrt;
  93. pre->RTag=Thread; /* 最后一个结点线索化 */
  94. (*Thrt)->rchild=pre;
  95. }
  96. return OK;
  97. }
  98. /* 中序遍历二叉线索树T(头结点)的非递归算法 */
  99. Status InOrderTraverse_Thr(BiThrTree T)
  100. {
  101. BiThrTree p;
  102. p=T->lchild; /* p指向根结点 */
  103. while(p!=T)
  104. { /* 空树或遍历结束时,p==T */
  105. while(p->LTag==Link)
  106. p=p->lchild;
  107. if(!visit(p->data)) /* 访问其左子树为空的结点 */
  108. return ERROR;
  109. while(p->RTag==Thread&&p->rchild!=T)
  110. {
  111. p=p->rchild;
  112. visit(p->data); /* 访问后继结点 */
  113. }
  114. p=p->rchild;
  115. }
  116. return OK;
  117. }
  118. int main()
  119. {
  120. BiThrTree H,T;
  121. printf("请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')\n");
  122. CreateBiThrTree(&T); /* 按前序产生二叉树 */
  123. InOrderThreading(&H,T); /* 中序遍历,并中序线索化二叉树 */
  124. printf("中序遍历(输出)二叉线索树:\n");
  125. InOrderTraverse_Thr(H); /* 中序遍历(输出)二叉线索树 */
  126. printf("\n");
  127. return 0;
  128. }

测试输出

  1. 请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')
  2. ABDH##I##EJ###CF##G##
  3. 中序遍历(输出)二叉线索树:
  4. H D I B J E A F C G