在2022年快手应届生后端面试中遇到了后续遍历二叉树转双向链表的问题,有一种简单的思路是后续遍历二叉树转集合,再转为双向链表,本人曾在剑指offer中做过一道二叉树与双向链表,题中是中序遍历二叉搜索树,将题解中的遍历顺序改一改便可得到后续遍历二叉树转双向链表。
注:先序遍历不可用,因为
root.left = pre;
pre = root;
dfs(root.left);
相当于无限dfs root,会导致stack overflow。
class Solution {
Node pre,head;//pre指针用于保存中序遍历的前一个节点,head指针用于记录排序链表的头节点。
public Node treeToDoublyList(Node root) {
if(root == null){
return null;
}
dfs(root);
head.left = pre;
pre.right = head;//进行头节点和尾节点的相互指向
return head;
}
public void dfs(Node root){//
if(root == null){
return;
}
//后序遍历,遍历顺序就是双线链表的建立顺序。后序遍历中,修改每个节点左右指针,连成双向循环链表。
dfs(root.left);
dfs(root.right);
if (pre != null) pre.right = root;//前一个节点指向当前节点
else head = root; // 链表头结点
root.left = pre;//当前节点指向前一个节点
pre = root;//pre 移到当前的root
}
}
时间复杂度 O(N): N 为二叉树的节点数,中序遍历需要访问所有节点。
空间复杂度 O(N): 最差情况下,即树退化为链表时,递归深度达到 N,系统使用 O(N)栈空间。