LC144 二叉树的前序遍历
一.任务描述:
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
解释:

示例 2:
输入:root = [1,2,3,4,5,null,8,null,null,6,7,9]
输出:[1,2,4,5,6,7,3,8,9]
解释:

示例 3:
输入:root = []
输出:[]
示例 4:
输入:root = [1]
输出:[1]
二.解题思路:
核心思想
利用树中空闲的指针来记录回溯路径,从而避免使用栈或递归带来的额外空间开销。
算法步骤
初始化:从根节点开始遍历
左子树处理:
如果当前节点没有左子树,直接访问该节点并转向右子树
如果有左子树,找到当前节点在中序遍历下的前驱节点
线索建立与断开:
第一次访问:建立线索,访问当前节点,转向左子树
第二次访问:断开线索,转向右子树
算法优势
空间复杂度:O(1),只使用常数额外空间
时间复杂度:O(n),每个节点被访问1-2次
不修改树结构:遍历完成后恢复原始树结构
三.代码实现:
C
/*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/
/*** Note: The returned array must be malloced, assume caller calls free().*/
int* preorderTraversal(struct TreeNode* root, int* returnSize) {if (root == NULL) {*returnSize = 0;return NULL;}int* result = (int*)malloc(sizeof(int) * 100); // 预估大小int count = 0;struct TreeNode* current = root;while (current != NULL) {if (current->left == NULL) {// 如果没有左子树,访问当前节点并转向右子树result[count++] = current->val;current = current->right;} else {// 找到当前节点的前驱节点struct TreeNode* predecessor = current->left;while (predecessor->right != NULL && predecessor->right != current) {predecessor = predecessor->right;}if (predecessor->right == NULL) {// 第一次访问,建立线索并访问当前节点result[count++] = current->val;predecessor->right = current;current = current->left;} else {// 第二次访问,恢复树结构predecessor->right = NULL;current = current->right;}}}*returnSize = count;return result;
}四.总结:
核心技巧:
线索利用:巧妙利用空闲的右指针记录回溯路径
两次访问策略:第一次访问建立线索,第二次访问恢复结构
空间换时间思维反转:用时间上的轻微代价(重复访问)换取空间的大幅优化
