力扣94题:二叉树的中序遍历

打印 上一主题 下一主题

主题 808|帖子 808|积分 2424

力扣94题:二叉树的中序遍历(C语言实现详解)

题目形貌

给定一个二叉树的根节点 root ,返回它的中序遍历(Inorder Traversal)。
中序遍历的规则是:

  • 先访问左子树;
  • 再访问根节点;
  • 末了访问右子树。
示例 1:
  1. 输入:root = [1,null,2,3]
  2. 输出:[1,3,2]
复制代码
示例 2:
  1. 输入:root = []
  2. 输出:[]
复制代码
示例 3:
  1. 输入:root = [1]
  2. 输出:[1]
复制代码

解题思绪


  • 递归方法:
    利用递归函数模拟中序遍历的规则,依次访问左子树、根节点、右子树,简单直观。
  • 迭代方法(栈):
    利用栈显式地模拟递归过程。每次先将左子树依次压入栈中,访问到最左节点后逐步出栈,同时转向右子树。
  • Morris 遍历(优化空间):
    通过线索化的方式,将树布局转换为一个遍历链表,从而实现                                              O                               (                               1                               )                                      O(1)                        O(1) 额外空间的中序遍历。

方法一:递归实现

代码实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义二叉树节点结构
  4. struct TreeNode {
  5.     int val;
  6.     struct TreeNode *left;
  7.     struct TreeNode *right;
  8. };
  9. // 辅助函数:递归中序遍历
  10. void inorderHelper(struct TreeNode *root, int *result, int *returnSize) {
  11.     if (root == NULL) return;
  12.     // 递归遍历左子树
  13.     inorderHelper(root->left, result, returnSize);
  14.     // 记录当前节点值
  15.     result[(*returnSize)++] = root->val;
  16.     // 递归遍历右子树
  17.     inorderHelper(root->right, result, returnSize);
  18. }
  19. // 主函数:返回中序遍历结果
  20. int* inorderTraversal(struct TreeNode *root, int *returnSize) {
  21.     *returnSize = 0;
  22.     // 为结果数组分配空间(假设最多有 100 个节点)
  23.     int *result = (int *)malloc(100 * sizeof(int));
  24.     if (result == NULL) return NULL;
  25.     inorderHelper(root, result, returnSize);
  26.     return result;
  27. }
  28. // 测试函数
  29. int main() {
  30.     // 构造二叉树 [1, null, 2, 3]
  31.     struct TreeNode node3 = {3, NULL, NULL};
  32.     struct TreeNode node2 = {2, &node3, NULL};
  33.     struct TreeNode root = {1, NULL, &node2};
  34.     int returnSize;
  35.     int *result = inorderTraversal(&root, &returnSize);
  36.     printf("中序遍历结果: ");
  37.     for (int i = 0; i < returnSize; i++) {
  38.         printf("%d ", result[i]);
  39.     }
  40.     printf("\n");
  41.     free(result); // 释放内存
  42.     return 0;
  43. }
复制代码

复杂度分析



  • 时间复杂度:
                                                  O                               (                               n                               )                                      O(n)                        O(n),其中                                              n                                      n                        n 是二叉树的节点数,每个节点访问一次。
  • 空间复杂度:
                                                  O                               (                               h                               )                                      O(h)                        O(h),其中                                              h                                      h                        h 是二叉树的高度,递归栈的最大深度为                                              h                                      h                        h。

方法二:迭代实现

代码实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义二叉树节点结构
  4. struct TreeNode {
  5.     int val;
  6.     struct TreeNode *left;
  7.     struct TreeNode *right;
  8. };
  9. // 主函数:返回中序遍历结果
  10. int* inorderTraversal(struct TreeNode *root, int *returnSize) {
  11.     *returnSize = 0;
  12.     int *result = (int *)malloc(100 * sizeof(int)); // 假设最多有 100 个节点
  13.     if (result == NULL) return NULL;
  14.     struct TreeNode *stack[100]; // 用数组模拟栈
  15.     int top = -1; // 栈顶指针
  16.     struct TreeNode *current = root;
  17.     while (current != NULL || top != -1) {
  18.         // 将所有左子节点入栈
  19.         while (current != NULL) {
  20.             stack[++top] = current;
  21.             current = current->left;
  22.         }
  23.         // 弹出栈顶节点
  24.         current = stack[top--];
  25.         result[(*returnSize)++] = current->val;
  26.         // 访问右子树
  27.         current = current->right;
  28.     }
  29.     return result;
  30. }
  31. // 测试函数
  32. int main() {
  33.     // 构造二叉树 [1, null, 2, 3]
  34.     struct TreeNode node3 = {3, NULL, NULL};
  35.     struct TreeNode node2 = {2, &node3, NULL};
  36.     struct TreeNode root = {1, NULL, &node2};
  37.     int returnSize;
  38.     int *result = inorderTraversal(&root, &returnSize);
  39.     printf("中序遍历结果: ");
  40.     for (int i = 0; i < returnSize; i++) {
  41.         printf("%d ", result[i]);
  42.     }
  43.     printf("\n");
  44.     free(result); // 释放内存
  45.     return 0;
  46. }
复制代码

复杂度分析



  • 时间复杂度:
                                                  O                               (                               n                               )                                      O(n)                        O(n),其中                                              n                                      n                        n 是二叉树的节点数。
  • 空间复杂度:
                                                  O                               (                               h                               )                                      O(h)                        O(h),其中                                              h                                      h                        h 是二叉树的高度,显式栈的最大深度为                                              h                                      h                        h。

方法三:Morris 遍历(优化空间)

代码实现

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. // 定义二叉树节点结构
  4. struct TreeNode {
  5.     int val;
  6.     struct TreeNode *left;
  7.     struct TreeNode *right;
  8. };
  9. // 主函数:返回中序遍历结果
  10. int* inorderTraversal(struct TreeNode *root, int *returnSize) {
  11.     *returnSize = 0;
  12.     int *result = (int *)malloc(100 * sizeof(int)); // 假设最多有 100 个节点
  13.     if (result == NULL) return NULL;
  14.     struct TreeNode *current = root, *pre;
  15.     while (current != NULL) {
  16.         if (current->left == NULL) {
  17.             result[(*returnSize)++] = current->val;
  18.             current = current->right;
  19.         } else {
  20.             pre = current->left;
  21.             while (pre->right != NULL && pre->right != current) {
  22.                 pre = pre->right;
  23.             }
  24.             if (pre->right == NULL) {
  25.                 pre->right = current;
  26.                 current = current->left;
  27.             } else {
  28.                 pre->right = NULL;
  29.                 result[(*returnSize)++] = current->val;
  30.                 current = current->right;
  31.             }
  32.         }
  33.     }
  34.     return result;
  35. }
  36. // 测试函数
  37. int main() {
  38.     // 构造二叉树 [1, null, 2, 3]
  39.     struct TreeNode node3 = {3, NULL, NULL};
  40.     struct TreeNode node2 = {2, &node3, NULL};
  41.     struct TreeNode root = {1, NULL, &node2};
  42.     int returnSize;
  43.     int *result = inorderTraversal(&root, &returnSize);
  44.     printf("中序遍历结果: ");
  45.     for (int i = 0; i < returnSize; i++) {
  46.         printf("%d ", result[i]);
  47.     }
  48.     printf("\n");
  49.     free(result); // 释放内存
  50.     return 0;
  51. }
复制代码

复杂度分析



  • 时间复杂度:
                                                  O                               (                               n                               )                                      O(n)                        O(n),每个节点访问两次。
  • 空间复杂度:
                                                  O                               (                               1                               )                                      O(1)                        O(1),无需额外栈空间。

总结

方法时间复杂度空间复杂度特点递归                                                  O                                  (                                  n                                  )                                          O(n)                           O(n)                                                  O                                  (                                  h                                  )                                          O(h)                           O(h)简单易实现,但依赖递归栈。迭代(栈)                                                  O                                  (                                  n                                  )                                          O(n)                           O(n)                                                  O                                  (                                  h                                  )                                          O(h)                           O(h)显式利用栈,得当较大的二叉树。Morris 遍历                                                  O                                  (                                  n                                  )                                          O(n)                           O(n)                                                  O                                  (                                  1                                  )                                          O(1)                           O(1)无额外空间需求,但实现较复杂。 不同方法得当不同场景,推荐优先利用递归和迭代方法,Morris 遍历得当对空间要求极高的情况。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表