题目来源:严蔚敏《数据结构》C语言版本习题册 6.70

【题目】6.70
如果用大写字母标识二叉树结点,则一棵二叉树可以用符合下面语法图的字符序列表示。试写一个递归算法,由这种形式的字符序列,建立相应的二叉树的二叉链表存储结构
根据 广义表GList 创建 二叉树BiTree(严蔚敏《数据结构》6.70) - 图1

【注意】这是我一开始犯的错误
根据以上匹配的公式得出这个测试数据:A(B(#,D(#,#)),C(E(#,F(#,#)),#)) —>这个是错的
【理解一下公式】

  1. 若二叉树为空 —>#
  2. 若二叉树存在 —> ‘字母’
    • 二叉树有孩子 —> ( , )
    • 没有孩子 —> `` 直接没有东西

【测试数据】A(B(#,D),C(E(#,F),#))
【思路】递归定义使用递归函数

【答案】

  1. // @Version:最新
  2. // @测试数据:A(B(#,D),C(E(#,F),#))
  3. // @Time:20181005
  4. Status CreateBiTreeByGList2(BiTree *pT) {
  5. char c;
  6. while (1) {
  7. c = getchar();
  8. if (c=='#') *pT = NULL; //空树
  9. else if (c>='A' && c<='Z') {
  10. *pT = (BiTNode *)malloc(sizeof(BiTNode)); if (!*pT) exit(OVERFLOW);
  11. (*pT)->data = c;
  12. (*pT)->lchild=(*pT)->rchild=NULL;
  13. }
  14. else if (c=='(') {
  15. CreateBiTreeByGList2( &(*pT)->lchild );
  16. CreateBiTreeByGList2( &(*pT)->rchild );
  17. }
  18. else
  19. break;
  20. }
  21. return OK;
  22. }

【完整代码】

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #ifndef BASE
  5. #define BASE
  6. #define TRUE 1
  7. #define FALSE 0
  8. #define OK 1
  9. #define ERROR 0
  10. #define INFEASIBLE -1
  11. #define OVERFLOW -2
  12. typedef int Status;
  13. typedef int bool;
  14. #endif
  15. #define TElemType char //固定为char,若修改需要修改方法
  16. typedef struct BiTNode { // 结点结构
  17. TElemType data;
  18. struct BiTNode *lchild, *rchild; // 左右孩子指针
  19. }BiTNode, *BiTree;
  20. void visit(TElemType e) {
  21. printf("%c", e);
  22. }
  23. // 先序遍历二叉树
  24. void PreOrder(BiTree T) { // - 递归
  25. if (!T) return ;
  26. visit(T->data);
  27. PreOrder(T->lchild);
  28. PreOrder(T->rchild);
  29. }
  30. // 中序遍历二叉树
  31. void InOrder(BiTree T) { // - 递归
  32. if (!T) return ;
  33. InOrder(T->lchild);
  34. visit(T->data);
  35. InOrder(T->rchild);
  36. }
  37. // 后序遍历二叉树
  38. void PostOrder(BiTree T) { // - 递归
  39. if (!T) return ;
  40. PostOrder(T->lchild);
  41. PostOrder(T->rchild);
  42. visit(T->data);
  43. }
  44. // 6.70 由广义表形式的输入建立二叉链表
  45. // @Version:0.0.1
  46. // @测试数据:A(B(#,D(#,#)),C(E(#,F(#,#)),#))
  47. // @Time:20181003
  48. // @Desc:公式理解错误-->测试数据出错
  49. Status CreateBiTreeByGList(BiTree *pT) {
  50. char c;
  51. BiTNode *p;
  52. c = getchar();
  53. if (c=='#') p=NULL; //空子树
  54. else {
  55. p = (BiTNode *)malloc(sizeof(BiTNode)); if (!p) exit(OVERFLOW);
  56. p->data=c; //赋值
  57. if (getchar()!='(') return ERROR; //格式错误
  58. if ( !CreateBiTreeByGList( &p->lchild ) ) return ERROR; //建立左子树
  59. if (getchar()!=',') return ERROR; //格式错误
  60. if ( !CreateBiTreeByGList( &p->rchild ) ) return ERROR; //建立右子树
  61. if (getchar()!=')') return ERROR; //格式错误
  62. }
  63. *pT = p; //把p传出去
  64. return TRUE;
  65. }
  66. // @Version:最新
  67. // @测试数据:A(B(#,D),C(E(#,F),#))
  68. // @Time:20181005
  69. Status CreateBiTreeByGList2(BiTree *pT) {
  70. char c;
  71. while (1) {
  72. c = getchar();
  73. if (c=='#') *pT = NULL; //空树
  74. else if (c>='A' && c<='Z') {
  75. *pT = (BiTNode *)malloc(sizeof(BiTNode)); if (!*pT) exit(OVERFLOW);
  76. (*pT)->data = c;
  77. (*pT)->lchild=(*pT)->rchild=NULL;
  78. }
  79. else if (c=='(') {
  80. CreateBiTreeByGList2( &(*pT)->lchild );
  81. CreateBiTreeByGList2( &(*pT)->rchild );
  82. }
  83. else
  84. break;
  85. }
  86. return OK;
  87. }
  88. int main() {
  89. /* 6.70测试数据
  90. A(B(#,D),C(E(#,F),#))
  91. */
  92. BiTree T;
  93. int cnt;
  94. cnt = CreateBiTreeByGList2(&T);
  95. if (cnt) {
  96. printf("二叉链表:\n");
  97. PreOrder(T);printf("\n");
  98. InOrder(T);printf("\n");
  99. PostOrder(T);printf("\n");
  100. } else {
  101. printf("输入不规范\n");
  102. }
  103. return 0;
  104. }

错误记录

版本:Version0.0.1
时间:20181005

【测试数据】A(B(#,D(#,#)),C(E(#,F(#,#)),#))
【答案】

  1. // v0.0.1
  2. // 6.70 由广义表形式的输入建立二叉链表
  3. Status CreateBiTreeByGList(BiTree *pT) {
  4. char c;
  5. BiTNode *p;
  6. c = getchar();
  7. if (c=='#') p=NULL; //空子树
  8. else {
  9. p = (BiTNode *)malloc(sizeof(BiTNode)); if (!p) exit(OVERFLOW);
  10. p->data=c; //赋值
  11. if (getchar()!='(') return ERROR; //格式错误
  12. if ( !CreateBiTreeByGList( &p->lchild ) ) return ERROR; //建立左子树
  13. if (getchar()!=',') return ERROR; //格式错误
  14. if ( !CreateBiTreeByGList( &p->rchild ) ) return ERROR; //建立右子树
  15. if (getchar()!=')') return ERROR; //格式错误
  16. }
  17. *pT = p; //把p传出去
  18. return TRUE;
  19. }

【完整代码】

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #ifndef BASE
  5. #define BASE
  6. #define TRUE 1
  7. #define FALSE 0
  8. #define OK 1
  9. #define ERROR 0
  10. #define INFEASIBLE -1
  11. #define OVERFLOW -2
  12. typedef int Status;
  13. typedef int bool;
  14. #endif
  15. #define TElemType char //固定为char,若修改需要修改方法
  16. typedef struct BiTNode { // 结点结构
  17. TElemType data;
  18. struct BiTNode *lchild, *rchild; // 左右孩子指针
  19. }BiTNode, *BiTree;
  20. void visit(TElemType e) {
  21. printf("%c", e);
  22. }
  23. // 先序遍历二叉树
  24. void PreOrder(BiTree T) { // - 递归
  25. if (!T) return ;
  26. visit(T->data);
  27. PreOrder(T->lchild);
  28. PreOrder(T->rchild);
  29. }
  30. // 中序遍历二叉树
  31. void InOrder(BiTree T) { // - 递归
  32. if (!T) return ;
  33. InOrder(T->lchild);
  34. visit(T->data);
  35. InOrder(T->rchild);
  36. }
  37. // 后序遍历二叉树
  38. void PostOrder(BiTree T) { // - 递归
  39. if (!T) return ;
  40. PostOrder(T->lchild);
  41. PostOrder(T->rchild);
  42. visit(T->data);
  43. }
  44. // 6.70 由广义表形式的输入建立二叉链表
  45. Status CreateBiTreeByGList(BiTree *pT) {
  46. char c;
  47. BiTNode *p;
  48. c = getchar();
  49. if (c=='#') p=NULL; //空子树
  50. else {
  51. p = (BiTNode *)malloc(sizeof(BiTNode)); if (!p) exit(OVERFLOW);
  52. p->data=c; //赋值
  53. if (getchar()!='(') return ERROR; //格式错误
  54. if ( !CreateBiTreeByGList( &p->lchild ) ) return ERROR; //建立左子树
  55. if (getchar()!=',') return ERROR; //格式错误
  56. if ( !CreateBiTreeByGList( &p->rchild ) ) return ERROR; //建立右子树
  57. if (getchar()!=')') return ERROR; //格式错误
  58. }
  59. *pT = p; //把p传出去
  60. return TRUE;
  61. }
  62. int main() {
  63. /* 6.70测试数据
  64. A(B(#,D(#,#)),C(E(#,F(#,#)),#))
  65. */
  66. BiTree T;
  67. int cnt;
  68. cnt = CreateBiTreeByGList(&T);
  69. if (cnt) {
  70. printf("二叉链表:\n");
  71. PreOrder(T);printf("\n");
  72. InOrder(T);printf("\n");
  73. PostOrder(T);printf("\n");
  74. } else {
  75. printf("输入不规范\n");
  76. }
  77. return 0;
  78. }