• 算法入门 | 二叉树的递归遍历、递归创建系列(递归)


    目录

    1. 二叉树的遍历规则

    2. 二叉树的结构体设计 【leftchild  data  rightchild】

    3. 二叉树的递归先序、中序、后序遍历

    4. 利用已知字符串(二叉树的先序序列)递归创建一棵二叉树

    (1)购买节点函数

    (2)创建二叉树

    5. 使用先序遍历序列和中序遍历序列创建一棵二叉树

    6. 使用中序遍历序列和后序遍历序列创建一棵二叉树

     7. 对二叉树的物理存储数组进行递归先序、中序、后序遍历


    1. 二叉树的遍历规则

    先序遍历: -> 左 -> 右;中序遍历: 左 -> -> 右;后序遍历:左 -> 右 ->

    2. 二叉树的结构体设计 【leftchild  data  rightchild】

    1. typedef char ELEMTYPE;//typedef给char类型起别名ELEMTYPE
    2. //二叉树结构体设计
    3. typedef struct BtNode
    4. {
    5. struct BtNode* leftchild;
    6. ELEMTYPE data;
    7. struct BtNode* rightchild;
    8. }BtNode,* PBtNode;

    3. 二叉树的递归先序、中序、后序遍历

    1. void PreOrder(struct BtNode* ptr) //先序遍历(根左右)
    2. {
    3. if (nullptr == ptr) return;
    4. printf("%3c", ptr->data);
    5. PreOrder(ptr->leftchild);
    6. PreOrder(ptr->rightchild);
    7. }
    8. void InOrder(struct BtNode* ptr) //中序遍历(左根右)
    9. {
    10. if (nullptr == ptr) return;
    11. InOrder(ptr->leftchild);
    12. printf("%3c", ptr->data);
    13. InOrder(ptr->rightchild);
    14. }
    15. void LastOrder(struct BtNode* ptr) //后序遍历(左右根)
    16. {
    17. if (nullptr == ptr) return;
    18. LastOrder(ptr->leftchild);
    19. LastOrder(ptr->rightchild);
    20. printf("%3c", ptr->data);
    21. }

    4. 利用已知字符串(二叉树的先序序列)递归创建一棵二叉树

    (1)购买节点函数

    1. struct BtNode* Buynode()
    2. {
    3. BtNode* s = (BtNode*)malloc(sizeof(BtNode));
    4. if (s == nullptr) exit(1);
    5. memset(s, 0, sizeof(BtNode));//此处不要写sizeof(s),由于指针永远为4bit(32bit系统下)
    6. return s;
    7. }

    (2)创建二叉树

    注意:函数参数为引用!!确保每次递归时传参是对同一字符串前置++

    1. BtNode* CreateBT(const char*& str)//参数为引用!!是由于递归时传参为++str~为了保证每次++同步执行(即在同一个字符串序列)
    2. {
    3. //根据先序序列创建树~根左右
    4. if (str == nullptr || strlen(str) <= 0) return nullptr;//空树
    5. BtNode* s = nullptr;
    6. if (*str != '#')
    7. {
    8. s = Buynode();
    9. s->data = *str;//根
    10. s->leftchild = CreateBT(++str);//左
    11. s->rightchild = CreateBT(++str);//右
    12. }
    13. return s;
    14. }
    15. int main()
    16. {
    17. const char* str = "ABC##DE##F##G#H##";
    18. BtNode* s=CreateBT(str);
    19. PreOrder(s);
    20. printf("\n");
    21. InOrder(s);
    22. printf("\n");
    23. LastOrder(s);
    24. printf("\n");
    25. return 0;
    26. }

    运行结果如图:

    5. 使用先序遍历序列和中序遍历序列创建一棵二叉树

    1. //根据先序遍历+中序遍历创建一棵二叉树
    2. int Find(const char* istr, int n, char str) //中序序列中找根对应的下标
    3. {
    4. int pos = -1;
    5. for (int i = 0; i < n; ++i)
    6. {
    7. if (istr[i] == str)
    8. {
    9. pos = i;
    10. break;
    11. }
    12. }
    13. return pos;
    14. }
    15. BtNode* CreatePITree(const char* pstr, const char* istr, int n)//此处n代表规模
    16. {
    17. BtNode* s = nullptr;
    18. if (n > 0)
    19. {
    20. s = Buynode();
    21. s->data = pstr[0];//先序首位为根
    22. int pos = Find(istr, n, pstr[0]);//中序序列中找根对应的下标
    23. if (pos == -1) exit(1);
    24. s->leftchild = CreatePITree(pstr+1,istr,pos);
    25. s->rightchild = CreatePITree(pstr+pos+1,istr+pos+1,n-pos-1);
    26. }
    27. return s;
    28. }
    29. BtNode* CreatePIT(const char* pstr, const char* istr)
    30. {
    31. int n = strlen(pstr);
    32. int m = strlen(istr);
    33. if (pstr == nullptr || istr == nullptr || n < 1 || m < 1 || n != m) return nullptr;
    34. else return CreatePITree(pstr, istr, n);
    35. }
    36. int main()
    37. {
    38. //const char* str = "ABC##DE##F##G#H##";
    39. //BtNode* s=CreateBT(str);
    40. const char* pstr = "ABCDEFGH";
    41. const char* istr = "CBEDFAGH";
    42. BtNode* s = CreatePIT(pstr, istr);
    43. PreOrder(s);
    44. printf("\n");
    45. InOrder(s);
    46. printf("\n");
    47. LastOrder(s);
    48. printf("\n");
    49. return 0;
    50. }

    6. 使用中序遍历序列和后序遍历序列创建一棵二叉树

    1. //根据中序遍历+后序遍历创建一棵二叉树
    2. BtNode* CreateILTree(const char* istr, const char* lstr, int n)//此处n代表规模
    3. {
    4. BtNode* s = nullptr;
    5. if (n > 0)
    6. {
    7. s = Buynode();
    8. s->data = lstr[n - 1];//后序遍历的最后一个为根
    9. int pos = Find(istr, n, lstr[n - 1]);
    10. s->leftchild = CreateILTree(istr,lstr,pos);
    11. s->rightchild = CreateILTree(istr+pos+1,lstr+pos,n-pos-1);
    12. }
    13. return s;
    14. }
    15. BtNode* CreateILT(const char* istr, const char* lstr)
    16. {
    17. int n = strlen(istr);
    18. int m = strlen(lstr);
    19. if (nullptr == istr || nullptr == lstr || n < 1 || m < 1 || n != m) return nullptr;
    20. else return CreateILTree(istr, lstr, n);
    21. }
    22. int main()
    23. {
    24. //const char* str = "ABC##DE##F##G#H##";
    25. //BtNode* s=CreateBT(str);
    26. const char* pstr = "ABCDEFGH";
    27. const char* istr = "CBEDFAGH";
    28. const char* lstr = "CEFDBHGA";
    29. //BtNode* s = CreatePIT(pstr, istr);
    30. BtNode* s = CreateILT(istr, lstr);
    31. PreOrder(s);
    32. printf("\n");
    33. InOrder(s);
    34. printf("\n");
    35. LastOrder(s);
    36. printf("\n");
    37. return 0;
    38. }

     7. 对二叉树的物理存储(数组)进行递归先序、中序、后序遍历

    主要依据:二叉树的物理存储对应逻辑存储的关系。

    二叉树物理下标为i:其左孩子对应下标为i*2+1;其右孩子对应下标为i*2+2

     

    1. //对二叉树的物理存储数组进行递归先序、中序、后序遍历
    2. void PreOrder(const int* nums, int i, int n)//遍历规模:i~n
    3. {
    4. if (i < n && nums[i] != -1) //i==n时规模为1
    5. {
    6. printf("%3d", nums[i]);//根
    7. PreOrder(nums, i * 2 + 1, n);//左 左子树下标:i*2+1
    8. PreOrder(nums, i * 2 + 2, n);//右
    9. }
    10. }
    11. void InOrder(const int* nums, int i, int n)
    12. {
    13. if (i < n && nums[i] != -1)
    14. {
    15. InOrder(nums, i * 2 + 1, n);//左
    16. printf("%3d", nums[i]);//根
    17. InOrder(nums, i * 2 + 2, n);//右
    18. }
    19. }
    20. void LastOrder(const int* nums, int i, int n)
    21. {
    22. if (i < n && nums[i] != -1)
    23. {
    24. LastOrder(nums, i * 2 + 1, n);//左
    25. LastOrder(nums, i * 2 + 2, n);//右
    26. printf("%3d", nums[i]);//根
    27. }
    28. }
    29. int main()
    30. {
    31. const int nums[] = {31,23,12,66,-1,5,17,70,62,-1,-1,-1,88,-1,55};
    32. int n = sizeof(nums) / sizeof(nums[0]);
    33. PreOrder(nums, 0, n);
    34. printf("\n");
    35. InOrder(nums, 0, n);
    36. printf("\n");
    37. LastOrder(nums, 0, n);
    38. printf("\n");
    39. return 0;
    40. }
  • 相关阅读:
    防抖跟节流
    maven_0
    Flutter 开发问题记录
    springboot 整合 dubbo 实现分组聚合
    【数据库编程-SQLite3(三)】Ubuntu下sqlite3的使用
    ts 枚举类型原理及其应用详解
    Ribbon学习笔记一
    图表背后的故事:数据可视化的威力与影响
    最强大脑记忆曲线(2)——创建数据库
    红细胞膜包覆葫芦素B纳米结构脂质载体RBC-CuB-NLC /红细胞膜脂三尖杉酯碱脂质体
  • 原文地址:https://blog.csdn.net/m0_56194716/article/details/127983215