• 重建二叉树


    二叉树的建立:

    对于二叉树,如果单纯通过前序遍历或后序遍历以及中序遍历是无法唯一确定一棵二叉树的
    前序+中序
    后序+中序
    才可以唯一确定一棵二叉树。

    因此我们可以通过前序+中序或者后序+中序的结果对二叉树进行确定。


    假设一棵二叉树为如下:

    则前序和中序遍历的结果是:

    我们首先要对前序遍历和中序遍历的特点进行了解。
    如上图数组中,明显可以看到。在前序遍历中,数组第一个元素就是这棵树的Root,而中序遍历,则Root位于中间位置啦 ,但是在中序中
    Root(图中中序遍历数组 的“1”)左边是其左子树,而其右边是其右子树的节点值,于是我们大概可以确定这棵树了。

    那么左子树又如何确定呢?
    前序遍历结果:                   中序遍历结果:
    于是我们又可以确定如下:


    那么又子树呢?同样的嘛:

    一直这样迭代下去,肯定就可以了搞定了。

    1. #ifndef RECONSTRUCT_BINARY_TREE_H
    2. #define RECONSTRUCT_BINARY_TREE_H
    3. #include<iostream>
    4. struct TreeNode{
    5. int val;
    6. struct TreeNode *left;
    7. struct TreeNode *right;
    8. };
    9. struct TreeNode *reconstructBinaryTree(int *preorder,int *midorder,int length);
    10. struct TreeNode *reconstructCore(int *startPreorder,int *endPreorder,int *startMidorder,int *endMidorder);

    11. struct TreeNode *reconstructBinaryTree(int *preorder,int *midorder,int length){
    12. return reconstructCore(preorder,preorder+length-1,midorder,midorder+length-1);
    13. }
    14. struct TreeNode *reconstructCore(
    15. int *startPreorder,int *endPreorder,
    16. int *startMidorder,int *endMidorder){ //这里是关键,传入的参数是当前前序、中序的起始位置

    17. int rootValue=*startPreorder;
    18. struct TreeNode *root=new TreeNode; //核心部分,构建一个节点
    19. root->val=rootValue;
    20. root->left=root->right=NULL;
    21. if(startPreorder==endPreorder){
    22. if(startMidorder==endMidorder&&*startPreorder==*startMidorder){
    23. return root; //边界值的处理
    24. }else{
    25. throw("invalid input ");
    26. }
    27. }
    28. int *iter;
    29. int leftCount=0;
    30. for(iter=startMidorder; iter!=endMidorder; iter++){
    31. if(*iter==rootValue){
    32. break;
    33. }
    34. leftCount++;
    35. }
    36. if(iter!=startMidorder&&iter!=endMidorder){ //如果左右子树不为空
    37. root->left=reconstructCore(startPreorder+1,startPreorder+leftCount,startMidorder,iter-1);
    38. root->right=reconstructCore(startPreorder+leftCount+1,endPreorder,iter+1,endMidorder);
    39. }
    40. if(iter==startMidorder&&iter!=endMidorder){ //如果左子树为空
    41. root->left=NULL;
    42. root->right=reconstructCore(startPreorder+leftCount+1,endPreorder,iter+1,endMidorder);
    43. }
    44. if(iter!=startMidorder&&iter==endMidorder){ //如果右子树为空
    45. root->left=reconstructCore(startPreorder+1,startPreorder+leftCount,startMidorder,iter-1);
    46. root->right=NULL;
    47. }
    48. return root;
    49. }
    50. void preorderPrint(struct TreeNode *root){
    51. if(root==NULL){
    52. return;
    53. }
    54. std::cout<<root->val<<std::endl;
    55. preorderPrint(root->left);
    56. preorderPrint(root->right);
    57. }
    58. void midorderPrint(struct TreeNode *root){
    59. if(root==NULL){
    60. return;
    61. }
    62. preorderPrint(root->left);
    63. std::cout<<root->val<<std::endl;
    64. preorderPrint(root->right);
    65. }
    66. #endif
    1. int main(){
    2. int pre[8]={1,2,4,7,3,5,6,8};
    3. int mid[8]={4,7,2,1,5,3,8,6};
    4. struct TreeNode *root=reconstructBinaryTree(pre,mid,8);
    5. /*std::cout<<root->left->val<<std::endl;
    6. std::cout<<root->left->left->right->val<<std::endl;
    7. std::cout<<root->left->left->val<<std::endl;
    8. std::cout<<root->right->left->val<<std::endl;
    9. std::cout<<root->right->right->val<<std::endl;
    10. std::cout<<root->right->right->left->val<<std::endl; */
    11. preorderPrint(root);
    12. midorderPrint(root);
    13. }









  • 相关阅读:
    SiteMap 提交,并使用正确的方式提交给搜索引擎
    爱自己的人脸上散发的光芒是骗不了别人的,你会活在平静淡定喜悦中,绝少埋怨,鲜有不满,没有太多话需要澄清,说清楚,内心是一片宁静而有力量的海。
    PHP 调用webService方式
    Oracle数据库操作知道
    气泡 弹出 bootstrap-popover的配置与灵活应用
    mysql向表中某字段后追加一段字符串:
    LINUX 下安装一些东西,PHP Apach SSL 等
    在同一个页面上要使用多个百度分享,控件人分享的内容信息
    Linux study
    Mysql 备份
  • 原文地址:https://www.cnblogs.com/yml435/p/4655494.html
Copyright © 2020-2023  润新知