• 9 二叉树的重建--来源于沈钰S同学(舒姐)


    来源于沈钰S同学(舒姐)

    来源于沈钰S同学(舒姐)

    abyssfall的博客_CSDN博客-计科学子的头发账本,代码存档领域博主

    问题描述 :

    目的:现有两个结点序列,分别是对同一个二叉树进行前序遍历和中序遍历(或中序和后序)的结果。要求设计一个算法,重构该二叉树,并输出该二叉树按照后序(前序)遍历时的结点序列。假定二叉树所有的结点的数据域的值都不相同。二叉树的存储结构的建立参见二叉树应用1。

    一、已知前序和中序的结果,进行二叉树的重构:

    提示:preOrder按照先根再左再右的顺序递归遍历,inOrder按照先左再根再右的顺序递归遍历。

    举例说明:preOrder的输入pre={A,B,D,G,H,C,E,I,F},inOrder的输入in={G,D,H,B,A,E,I,C,F}。首先按preOrder遍历的顺序依次访问各结点。访问过程中,通过in得知各子树内inOrder遍历的顺序,从而重建以当前访问结点c为根的左子树与右子树。即:设preOrder遍历的当前结点为c,c在in中的位置为m,m左侧就是c的左子树,右侧就是c的右子树。同理递归。

    (2)

    参考函数原型:

    (1)//重建二叉树的存储结构 (外壳)
    template
    BinaryTreeNode *ReBuildTree_Pre_In(vector[ElemType] &pre, vector[ElemType] &in);

    (2)//重建二叉树的存储结构 (递归)
    template
    BinaryTreeNode *reConstructCore_Pre_In(vector[ElemType] &pre, vector[ElemType] &in, int preStart, int preEnd, int inStart, int inEnd );

    二、已知中序和后序的结果,进行二叉树的重构:

    可参考一的思路。

    参考函数原型:

    (1)//重建二叉树的存储结构 (外壳)
    template
    BinaryTreeNode *ReBuildTree_In_Post(vector[ElemType] &in, vector[ElemType] &post);

    (2)//重建二叉树的存储结构 (递归)
    template
    BinaryTreeNode *reConstructCore_In_Post(vector[ElemType] &in, vector[ElemType] &post, int inStart, int inEnd, int postStart, int postEnd );

    输入说明 :

    第一行:重构选择(0:前序中序重构  1:中序后序重构)  

    0:

    第二行:按前序遍历的结点序列,相邻结点用空格隔开

    第三行:按中序遍历的结点序列,相邻结点用空格隔开

    1:

    第二行:按中序遍历的结点序列,相邻结点用空格隔开

    第三行:按后序遍历的结点序列,相邻结点用空格隔开

    输出说明 :

    0:

    第一行:按后序遍历的结点序列,相邻结点用","隔开

    1:

    第一行:按前序遍历的结点序列,相邻结点用","隔开

    -----------

    0
    A B C D E
    B D C E A

    ----------------

    D,E,C,B,A

    1. #include
    2. using namespace std;
    3. template <class ElemType>
    4. struct BinaryTreeNode
    5. {
    6. ElemType data;
    7. BinaryTreeNode *left;
    8. BinaryTreeNode *right;
    9. };
    10. template <class ElemType>
    11. void cinin(string str, vector &a)
    12. {
    13. int len = str.length();
    14. string str0 = "";
    15. for (int i = 0; i < len; i++)
    16. {
    17. if (str[i] != ' ')
    18. {
    19. str0 += str[i];
    20. }
    21. else
    22. {
    23. a.push_back(str0);
    24. str0 = "";
    25. }
    26. }
    27. a.push_back(str0);
    28. }
    29. bool f = false;
    30. //前序遍历
    31. template <class ElemType>
    32. void visit1(BinaryTreeNode *head)
    33. {
    34. if (head)
    35. {
    36. if (f == false)
    37. {
    38. f = true;
    39. cout << head->data;
    40. }
    41. else
    42. {
    43. cout << "," << head->data;
    44. }
    45. }
    46. if (head->left)
    47. visit1(head->left);
    48. if (head->right)
    49. visit1(head->right);
    50. return;
    51. }
    52. //后序遍历
    53. template <class ElemType>
    54. void visit3(BinaryTreeNode *head)
    55. {
    56. if (head->left)
    57. visit3(head->left);
    58. if (head->right)
    59. visit3(head->right);
    60. if (head)
    61. {
    62. if (f == false)
    63. {
    64. f = true;
    65. cout << head->data;
    66. }
    67. else
    68. {
    69. cout << "," << head->data;
    70. }
    71. }
    72. return;
    73. }
    74. template <class ElemType>
    75. BinaryTreeNode *reConstructCore_Pre_In(vector &pre, vector &in)
    76. {
    77. if (pre.size() == 0)
    78. {
    79. return NULL;
    80. } //先序读完了,不进下一层递归了,没叶子了
    81. vector left_pre, right_pre, left_in, right_in; //总之分一下,左右子树咔咔一下准备进递归
    82. BinaryTreeNode *head = new BinaryTreeNode;
    83. head->data = pre[0];
    84. int root = 0;
    85. int inlen = in.size();
    86. for (int i = 0; i < inlen; i++)
    87. {
    88. if (pre[0] == in[i])
    89. {
    90. root = i;
    91. break;
    92. }
    93. else
    94. continue;
    95. } //找一下根结点
    96. for (int i = 0; i < root; i++)
    97. {
    98. left_in.push_back(in[i]); //中序遍历,根结点之前全是左子树
    99. left_pre.push_back(pre[i + 1]); //先序遍历,第一个是根节点,往后读取相同数量丢入左子树
    100. }
    101. for (int i = root + 1; i < inlen; i++)
    102. {
    103. right_in.push_back(in[i]); //中序遍历,根节点之后全是右子树
    104. right_pre.push_back(pre[i]); //先序遍历,往后读取相同数量丢入左子树
    105. }
    106. head->left = reConstructCore_Pre_In(left_pre, left_in); //新分好的左子树
    107. head->right = reConstructCore_Pre_In(right_pre, right_in); //新分好的右子树
    108. return head;
    109. }
    110. template <class ElemType>
    111. BinaryTreeNode *reConstructCore_In_Post(vector &in, vector &post)
    112. {
    113. if (post.size() == 0)
    114. {
    115. return NULL;
    116. } //先序读完了,不进下一层递归了,没叶子了
    117. vector left_in, right_in, left_post, right_post; //总之分一下,左右子树咔咔一下准备进递归
    118. BinaryTreeNode *head = new BinaryTreeNode;
    119. int postlen = post.size();
    120. head->data = post[postlen - 1]; //后序遍历末尾为根节点
    121. int root = 0;
    122. int inlen = in.size();
    123. for (int i = 0; i < inlen; i++)
    124. {
    125. if (post[postlen - 1] == in[i])
    126. {
    127. root = i;
    128. break;
    129. }
    130. else
    131. continue;
    132. } //找一下根结点在中序遍历的位置,分左右子树
    133. //cout << "root = " << root << "in[root] = " << in[root] << endl;
    134. for (int i = 0; i < root; i++)
    135. {
    136. left_in.push_back(in[i]); //中序遍历,根结点之前全是左子树
    137. left_post.push_back(post[i]); //后序遍历,往后读取相同数量丢入左子树
    138. }
    139. //for (int i = 0; i < root; i++)
    140. //{
    141. // cout << "left_in:" << endl;
    142. // cout << left_in[i] << " ";
    143. //}
    144. ///cout << endl;
    145. //for (int i = 0; i < root; i++)
    146. //{
    147. // cout << "left_post:" << endl;
    148. // cout << left_post[i] << " ";
    149. //}
    150. //cout << endl;
    151. for (int i = root + 1; i < inlen; i++)
    152. {
    153. right_in.push_back(in[i]); //中序遍历,根节点之后全是右子树
    154. right_post.push_back(post[i - 1]); //后序遍历,挨着上个循环结尾往后读取相同数量丢入左子树
    155. }
    156. //for (int i = 0; i < right_in.size(); i++)
    157. //{
    158. // cout << "right_in:" << endl;
    159. // cout << right_in[i] << " ";
    160. //}
    161. //cout << endl;
    162. //for (int i = 0; i < right_post.size(); i++)
    163. //{
    164. // cout << "right_post:" << endl;
    165. // cout << right_post[i] << " ";
    166. //}
    167. //cout << endl;
    168. head->left = reConstructCore_In_Post(left_in, left_post);
    169. head->right = reConstructCore_In_Post(right_in, right_post);
    170. return head;
    171. }
    172. int main()
    173. {
    174. char flag;
    175. cin >> flag;
    176. getchar();
    177. if (flag == '0')
    178. {
    179. string linepre;
    180. vector pre;
    181. getline(cin, linepre);
    182. cinin(linepre, pre);
    183. vector in;
    184. string linein;
    185. getline(cin, linein);
    186. cinin(linein, in);
    187. BinaryTreeNode *root = new BinaryTreeNode;
    188. root = reConstructCore_Pre_In(pre, in);
    189. visit3(root);
    190. }
    191. else if (flag == '1')
    192. {
    193. string linein;
    194. vector in;
    195. getline(cin, linein);
    196. cinin(linein, in);
    197. string linepost;
    198. vector post;
    199. getline(cin, linepost);
    200. cinin(linepost, post);
    201. BinaryTreeNode *root = new BinaryTreeNode;
    202. root = reConstructCore_In_Post(in, post);
    203. visit1(root);
    204. }
    205. getchar();
    206. getchar();
    207. return 0;
    208. }

  • 相关阅读:
    C++ | Leetcode C++题解之第198题打家劫舍
    Kotlin中循环语句
    【LeetCode】Day130-最长有效括号
    Android AccessibilityService
    上手阿里低代码引擎lowcode-engine
    组合导航:中海达iNAV2产品描述及接口描述
    创建ffmpeg vs2019工程
    更新andriod studio版本,项目编译报could not find org.junit.jupiter:junit-jupiter
    二、字符串 String
    11.1Spring基础(核心概念,创建和使用,简单读取)
  • 原文地址:https://blog.csdn.net/Ultravioletrays/article/details/126799803