Trees · Binary Tree Fundamentals

Flatten Binary Tree to Linked List

Rewiring a binary tree in place into a singly linked list (via each node's right pointer, left always null) that visits nodes in preorder, by processing right subtree then left subtree then the node itself and threading each newly-flattened piece onto a running "already flattened" pointer.

  • 7 min read
  • 10 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach
  3. A second flavor: a doubly linked list in inorder
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

Flattening turns a binary tree into a linked list without creating a single new node. Each node's right pointer becomes "next", and its left pointer is either cleared or reused as "previous". Interviews ask for two versions: a singly linked list in preorder, and a doubly linked list in inorder. The tricky part is order. A node can only point at the rest of the list once that rest exists.

We'll go from simple to more technical:

  1. The pattern: build the preorder list backwards, from its last node to its first.
  2. A second flavor: a doubly linked list in inorder.
  3. Where in-place flattening helps.
  4. The bugs: building in the wrong order and leaving old left pointers behind.

The approach

In the finished list, every node points at the node after it in preorder. The easy way to get that right is to build the list from its end. Visit the nodes in the exact reverse of preorder: right subtree, then left subtree, then the node itself. Keep prev, the first node of the part you've already built. Each node sets right = prev, clears left, and becomes the new prev.

Take this tree. Its preorder is 8, 3, 1, 6, 10, 9, 14.

8

3

10

1

6

9

14

8

3

10

1

6

9

14

The walk links the nodes in reverse preorder. Each one goes in front of the chain built so far:

StepNode linkedChain after the step
11414
299 → 14
31010 → 9 → 14
466 → 10 → 9 → 14
511 → 6 → 10 → 9 → 14
633 → 1 → 6 → 10 → 9 → 14
788 → 3 → 1 → 6 → 10 → 9 → 14

Java

TreeNode prev = null;

void flatten(TreeNode root) {
    if (root == null) return;
    flatten(root.right);   // flatten right first...
    flatten(root.left);    // ...then left...
    root.right = prev;     // ...so `prev` is always the correctly-flattened chain so far
    root.left = null;
    prev = root;
}

Python

class Solution:
    def __init__(self):
        self.prev = None

    def flatten(self, root: TreeNode | None) -> None:
        if root is None:
            return
        self.flatten(root.right)   # flatten right first...
        self.flatten(root.left)    # ...then left...
        root.right = self.prev     # ...so self.prev is always the correctly-flattened chain so far
        root.left = None
        self.prev = root

The first node to be linked is the last one in preorder (14). Its prev is still null, which is right: nothing comes after it. Every later node plugs itself in front. When the recursion gets back to the root, the whole list reads in preorder.

A second flavor: a doubly linked list in inorder

Now the list should follow inorder (1, 3, 6, 8, 9, 10, 14 for the tree above), with links both ways. right means "next" and left means "previous". This time the list is built from the front. Walk in ordinary inorder: left subtree, node, right subtree. prev is the node you visited just before this one. Link the two in both directions and move on. The first node you visit has no prev, so it becomes the head.

Java

TreeNode prev = null, head = null;

void convert(TreeNode node) {
    if (node == null) return;
    convert(node.left);
    if (prev == null) {
        head = node;          // the first node visited in inorder becomes the list's head
    } else {
        prev.right = node;    // link the previous node's "next" forward to this one
        node.left = prev;     // link this node's "previous" backward to the previous one
    }
    prev = node;
    convert(node.right);
}

Python

def tree_to_doubly_list(root: TreeNode | None) -> TreeNode | None:
    prev = head = None

    def convert(node: TreeNode | None) -> None:
        nonlocal prev, head
        if node is None:
            return
        convert(node.left)
        if prev is None:
            head = node           # the first node visited in inorder becomes the list's head
        else:
            prev.right = node     # link the previous node's "next" forward to this one
            node.left = prev      # link this node's "previous" backward to the previous one
        prev = node
        convert(node.right)

    convert(root)
    return head

Changing a node's left here is safe. By the time the walk reaches a node, its left subtree is already finished.

Where you'll see it

Flattening helps when you need a tree as a sequence and don't want to copy it. A classic use is merging two binary search trees. Flatten each one into a sorted list, merge the lists, then build a balanced tree from the result.

Which tool for which job?

You needUse
Preorder as a right-pointer listreverse preorder (right, left, node) linking to prev
The same with O(1) extra spaceat each node, move its left subtree in between the node and its right child, then step right (no recursion)
A sorted doubly linked list from a BSTinorder, linking prev both ways
Merge two BSTsflatten both to sorted lists, merge, rebuild balanced
The original tree keptbuild a new list instead

Common mistakes

MistakeWhat happensDo this instead
Flattening left before right with prevthe right subtree's head isn't readyright, then left, then the node
Not clearing leftstale links; not a clean listset left = null
A prev field kept across callsthe next call links to the old treereset it per call
Only next links in the doubly linked versionbackward walks breaklink both directions
Recursion on a very deep treestack overflowthe O(1)-space splice

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. Preorder visits left before right. So why does the flatten walk do the right subtree first?

Show answer

Each node points at the part of the list that comes after it. In preorder, that's the left subtree followed by the right subtree. So the right subtree's chain has to exist first, then the left one in front of it, then the node. Right, then left, then the node builds the list from its end.

2. After root.right = prev, why set root.left to null too?

Show answer

root.left still points at the old left child, which is now further down the list. A walk that only follows right would still work. But the result isn't a clean list: the node still looks like it has a left child, and anything that reads left will go wrong.

3. Why does the doubly linked version use plain inorder, while flatten uses the reverse order?

Show answer

The doubly linked version builds the list from the front. Each node links back to the node visited just before it, so the normal visiting order works. Flatten puts each node in front of a chain that must already exist, so it has to build from the end.

Key takeaways

  • Flatten to preorder by visiting right, left, then the node, and linking each node in front of prev.
  • After setting right, clear left, or the list keeps a stale pointer.
  • The doubly linked version walks in plain inorder and links each node to the one before it, both ways.
  • Both reuse the tree's own pointers and create no new nodes.

Quick revise

The whole skill on one page, for the night before an interview.

Everything from the lesson and the deep dive on one page. Skim it before practice or an interview, and open the full lesson for anything that doesn't ring a bell.

Pick the tool

You needUse
Preorder right-listright, left, node + prev
O(1) spacesplice left subtrees
Sorted DLL from a BSTinorder + prev both ways
Merge two BSTsflatten, merge, rebuild

Snippets worth knowing by heart

Java

for (TreeNode cur = root; cur != null; cur = cur.right) {
    if (cur.left == null) continue;
    TreeNode tail = cur.left;
    while (tail.right != null) tail = tail.right;   // rightmost of the left subtree
    tail.right = cur.right;
    cur.right = cur.left;
    cur.left = null;                                // no stale links
}

Python

def to_dll(root):
    head = prev = None
    def visit(node):
        nonlocal head, prev
        if node is None:
            return
        visit(node.left)
        if prev:
            prev.right, node.left = node, prev       # link both directions
        else:
            head = node
        prev = node
        visit(node.right)
    visit(root)
    return head

The traps

  • Left before right with prev: the right subtree's head isn't ready yet. Go right, then left, then the node.
  • Stale left: old links remain and the list isn't clean. Set left to null.
  • prev reused across calls: the next call links to the old tree. Reset it per call.
  • One-way DLL links: walking backward breaks. Set both prev and next.
  • Deep recursion: a very deep tree overflows the stack. Use the O(1)-space splice.

Staff-level points, one line each

  • Reverse postorder builds preorder backwards.
  • 200,000-node chain: recursion overflowed; the splice flatten didn't.
  • BST → sorted DLL by inorder; join ends for a circular list.
  • Two BSTs (heights 23, 21) merged into height 11 in O(m + n).

Say it in an interview

  • "I build the list backwards - right, left, node - so prev is always what comes next."
  • "For O(1) space I splice each left subtree in before the right one."
  • "An inorder walk of a BST gives a sorted doubly linked list."
  • "It reuses the tree's pointers, so no new nodes are allocated."

Practice

This skill comes with 10 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Flatten Binary Tree to Linked List free

Flatten Binary Tree to Linked List

MediumProCoding problemJava · Python

Rewire a binary tree in place into a chain that follows preorder (the node, then its left subtree, then its right subtree): afterwards every left pointer is null, and each right pointer leads to the next node in preorder.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Binary Tree to Doubly Linked List

MediumProCoding problemJava · Python

Given the root of a binary tree (all node values distinct), convert it in place into a doubly linked list following the tree's inorder traversal order. Reuse each node's left pointer as "previous" and right pointer as "next" - do not create new nodes.

The full statement, the examples and the hidden test suite are part of AI Proof Engineers Pro.

Practice Flatten Binary Tree to Linked List free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime