Threaded Binary Tree in Data Structure: Types and Traversal

Data Structures / Chapter 68 Thread Pointer Observatory
Threaded Binary Tree Types & Traversal

See how unused NULL links become useful predecessor and successor pointers. Learn single and double threading, forward and reverse Inorder Traversal, and tested C code with simple examples.

Ordinary Pointer vs Thread Pointer
10→ 20→ 25
Follow inorder successors without a stack
01 / Understand the problem first

What Is a Threaded Binary Tree in Data Structure?

Threaded Binary Tree in Data Structure: Types and Traversal

In a normal Binary Tree, each node normally has a left pointer and a right pointer. But many of these pointers are NULL because a node may not have both children. What if we use some of these empty pointers to help us visit the next node?

Simple Definition: A Threaded Binary Tree (TBT) is a Binary Tree in which selected NULL child pointers are replaced by special links called threads. In an Inorder Threaded Binary Tree, these threads can point to a node's Inorder predecessor or successor, helping traversal without a separate stack or recursion.

A predecessor means the node visited immediately before the current node. A successor means the node visited immediately after it. Both words are based on the chosen traversal order.

Everyday example: Imagine reading chapters in a book. A normal tree asks you to remember the page you came from. A threaded tree gives some pages a shortcut to the previous or next page in the reading order.
02 / One original tree, used throughout

Binary Tree Diagram Before Adding Threads

We will use these seven values: 40, 20, 60, 10, 30, 25 and 70. Notice that node 30 has only a left child, while node 60 has only a right child. These missing links make the example useful for understanding threading.

Pictorial Representation 1 — Ordinary Binary Tree (solid edges are real child links)
Figure 1: Only parent-to-child links are shown. Thread links will be explained separately to avoid confusing them with child edges.

For this original tree, the traversal orders are:

Inorder (Left, Root, Right)

10 → 20 → 25 → 30 → 40 → 60 → 70

Preorder / Postorder

Preorder: 40, 20, 10, 30, 25, 60, 70
Postorder: 10, 25, 30, 20, 70, 60, 40

How Many NULL Child Pointers Does It Have?

Seven nodes have 14 child-pointer fields in total. A non-empty tree with seven nodes has six real parent-to-child edges, so 14 − 6 = 8 NULL positions. In general, a Binary Tree with n nodes has n + 1 NULL child-pointer positions. Threading can reuse some or all of these positions.

NULL child positions = n + 1 (for n ≥ 1)
03 / Which pointer becomes a thread?

Types of Threaded Binary Trees

Threaded trees can be classified in two useful ways: which pointer is threaded and which traversal order defines the threads. The most common classroom example is Inorder Threading.

1. Left-Threaded Binary Tree

If a left child is missing, its left pointer can refer to its Inorder predecessor. Right pointers continue to represent ordinary right children in a left-only threaded design.

2. Right-Threaded Binary Tree

If a right child is missing, its right pointer can refer to its Inorder successor. This is especially useful for forward Inorder traversal.

3. Double-Threaded Binary Tree

Both missing left and missing right child links may become threads: left points to the predecessor and right points to the successor. This supports forward and reverse Inorder traversal.

4. Based on Traversal Order

Threads may be defined using Inorder, Preorder or Postorder relationships. The same link must always be interpreted according to the chosen type.

Important terminology: “Single-threaded” usually refers to threading in one direction (left-only or right-only). “Double-threaded” means both directions. It does not mean a node has two extra child nodes.
Type Unused Left Pointer Unused Right Pointer Usual Goal
Left-threaded (Inorder) Predecessor thread NULL if no child Backward links
Right-threaded (Inorder) NULL if no child Successor thread Forward links
Double-threaded (Inorder) Predecessor thread Successor thread Forward and backward
Preorder / Postorder threaded Threads refer to predecessor/successor in the named traversal; traversal algorithms differ Order-specific navigation
04 / Learn the node structure

Threaded Binary Tree Node Structure: lthread and rthread

Because a pointer may mean either a real child or a thread, we need extra flags (tags). In our C program, we use lthread and rthread.

Pictorial Representation 2 — Fields in a Double-Threaded Node
Figure 2: Real code may arrange these fields differently, but the idea remains the same.
Tag 0 = real child pointer   |   Tag 1 = thread pointer

Some textbooks use the opposite bit convention. Always read the definitions in the given question or program. The code below consistently uses 1 for a thread.

Example: In our tree, 30 has a real left child 25, but no right child. After double Inorder threading, 30's left tag is 0, and its right tag is 1 because the right pointer points to successor 40.
05 / See actual predecessor and successor links

Double-Threaded Binary Tree Example with Pointer Diagram

Inorder is 10, 20, 25, 30, 40, 60, 70. We attach a thread only where a real child pointer was originally NULL. Real child links remain unchanged.

10 → 20 Right thread: successor
25 → 20 Left thread: predecessor
30 → 40 Right thread: successor
60 → 40 Left thread: predecessor

These shortcut arrows are not new child edges. For example, 30's right pointer points to 40 as a thread, even though 40 is an ancestor rather than 30's child.

Pictorial Representation 3 — Complete Child and Thread Pointer Map
Node Left Pointer LTag Right Pointer RTag
10 THREAD → NULL 1 THREAD → 20 1
20 CHILD → 10 0 CHILD → 30 0
25 THREAD → 20 1 THREAD → 30 1
30 CHILD → 25 0 THREAD → 40 1
40 CHILD → 20 0 CHILD → 60 0
60 THREAD → 40 1 CHILD → 70 0
70 THREAD → 60 1 THREAD → NULL 1
Figure 3: Both directions are threaded. NULL at the first predecessor and last successor means that there is no such node. Some implementations use a special header/sentinel instead.
Do not mistake a thread for a child: Without flags, following threads as ordinary child links could revisit ancestors, create cycles in recursion, and cause incorrect memory freeing.
06 / Construction method

How to Create Inorder Threads Step by Step

One straightforward method starts with an ordinary linked Binary Tree. Perform a normal recursive Inorder walk once, maintaining a pointer previous to the most recently visited node.

  1. Start previous = NULL and visit the far-left node 10 first.
  2. If the current node has no real left child, change its left link into a thread pointing to previous.
  3. If previous exists and its right child is missing, make its right pointer thread to the current node.
  4. Update previous = current and continue the Inorder walk.
  5. At the end, the right thread of last node 70 points to NULL, because it has no successor.
Example: When we visit node 25, previous is 20. Since 25 has no left child, set 25's left thread to 20. Since node 20 already has a real right child 30, its right link is not changed into a thread.

The conversion itself uses recursion in the demonstrated program. The benefit of threading appears during later traversals, when we can walk Inorder without using a separate recursion stack.

07 / Most important algorithm

Inorder Traversal of Threaded Binary Tree without Stack or Recursion

For a double Inorder-threaded tree, first reach the leftmost real node. Then repeatedly follow one of two rules to get the next node.

Right tag = 1 → follow successor thread
Right tag = 0 → enter real right subtree, then go leftmost
  1. Start at root 40 and follow real left-child pointers 40 → 20 → 10. Visit 10.
  2. 10 has right thread to 20. Follow it and visit 20.
  3. 20 has real right child 30. Enter 30's subtree, then go left to 25. Visit 25.
  4. 25 has a right thread to 30. Visit 30.
  5. 30 has a right thread to 40. Visit 40.
  6. 40 has real right child 60. That subtree's leftmost real node is 60. Visit 60.
  7. 60 has real right child 70. Visit 70. Its right thread is NULL, so stop.
10→ 20→ 25→ 30→ 40→ 60→ 70
Visited Node How to Reach Next? Next Node
10Right thread20
20Real right child 30, then leftmost25
25Right thread30
30Right thread40
40Real right child 60, then leftmost60
60Real right child 70, then leftmost70
70Right thread → NULLStop

Inorder Traversal Pseudocode

Forward Inorder — no recursion or separate stack
current = LEFTMOST(root)

WHILE current is not NULL
    VISIT(current)

    IF current.rthread == 1
        current = current.right
    ELSE
        current = LEFTMOST(current.right)
Shortcut: When a right pointer is a thread, jump directly to the successor. When it is a child, explore the leftmost node of that right subtree.
08 / Walk backwards

Reverse Inorder Traversal in a Double-Threaded Binary Tree

Reverse Inorder visits nodes in Right → Root → Left order. Because double threading also stores predecessor links, we can walk backward without a separate stack.

Left tag = 1 → follow predecessor thread
Left tag = 0 → enter real left subtree, then go rightmost

Start at the rightmost node 70. Its left thread takes us to 60. Node 60's left thread takes us to 40. Node 40 has a real left subtree rooted at 20, whose rightmost node is 30. Continue similarly.

70→ 60→ 40→ 30→ 25→ 20→ 10
Reverse Inorder pseudocode
current = RIGHTMOST(root)

WHILE current is not NULL
    VISIT(current)

    IF current.lthread == 1
        current = current.left
    ELSE
        current = RIGHTMOST(current.left)
09 / Other threading orders

Preorder and Postorder Threaded Binary Tree Traversal

Threading is not restricted to Inorder. You can design threads around another traversal, but you must use its correct predecessor/successor rules.

Preorder Threading

Order: Root → Left → Right. For our tree: 40, 20, 10, 30, 25, 60, 70. A missing pointer may be used to store the next/previous node in Preorder, according to the chosen design.

Postorder Threading

Order: Left → Right → Root. For our tree: 10, 25, 30, 20, 70, 60, 40. Navigating to the next Postorder node can be harder, because it may require parent information or a special header.

Important: The C program in this chapter implements Inorder double threading, not Preorder or Postorder threading. Do not apply its successor algorithm unchanged to those other thread types. Threading alone does not guarantee equally simple O(1)-extra-space traversal for every order and representation.
10 / Interactive step-by-step practice

Threaded Binary Tree Traversal Visualizer

Choose forward or reverse Inorder. Press Next Visit to reveal the visited nodes and understand whether the next move follows a thread or a real child subtree. This is a guided trace of the same seven-node example.

Thread Pointer Trace Console

Step 0 of 7. Begin at the leftmost real node: 10. Use Next Visit to follow the inorder sequence.
10 20 25 30 40 60 70

This simulator is optional. The full dry run and pointer map above remain readable if a Blogger theme blocks JavaScript in posts.

11 / Compile and verify

Threaded Binary Tree Program in C with Inorder and Reverse Inorder Traversal

This complete C program first creates an ordinary seven-node tree. It converts missing child links into predecessor/successor threads using the Inorder sequence, then traverses forward and backward without recursion or a separate stack. The conversion step itself uses recursion.

The flags lthread and rthread are 0 for real children and 1 for threads. When freeing the tree, the function visits only real children, not thread pointers.

threaded_binary_tree_ch68.c — Complete C11 program
#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *left, *right;
    unsigned char lthread, rthread;
} Node;

Node *create(int value) {
    Node *p = malloc(sizeof *p);

    if (!p) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(EXIT_FAILURE);
    }

    p->data = value;
    p->left = p->right = NULL;
    p->lthread = p->rthread = 0;
    return p;
}

/* Run once on an ordinary tree, before any threads exist. */

void addThreads(Node *p, Node **previous) {
    if (!p) return;

    Node *originalLeft = p->left;
    Node *originalRight = p->right;

    addThreads(originalLeft, previous);

    if (originalLeft == NULL) {
        p->lthread = 1;
        p->left = *previous;
        /* Inorder predecessor, possibly NULL */
    }

    if (*previous && (*previous)->right == NULL) {
        (*previous)->rthread = 1;
        (*previous)->right = p;
        /* Inorder successor */
    }

    *previous = p;

    addThreads(originalRight, previous);
}

void convertToInorderThreads(Node *root) {
    Node *previous = NULL;

    addThreads(root, &previous);

    if (previous && previous->right == NULL) {
        previous->rthread = 1;
        previous->right = NULL;
        /* Last node has no successor */
    }
}

Node *leftmost(Node *p) {
    while (
        p &&
        p->lthread == 0 &&
        p->left
    ) {
        p = p->left;
    }

    return p;
}

Node *rightmost(Node *p) {
    while (
        p &&
        p->rthread == 0 &&
        p->right
    ) {
        p = p->right;
    }

    return p;
}

void inorderNoStack(Node *root) {
    for (
        Node *p = leftmost(root);
        p != NULL;
    ) {
        printf("%d ", p->data);

        p = p->rthread
            ? p->right
            : leftmost(p->right);
    }
}

void reverseInorderNoStack(Node *root) {
    for (
        Node *p = rightmost(root);
        p != NULL;
    ) {
        printf("%d ", p->data);

        p = p->lthread
            ? p->left
            : rightmost(p->left);
    }
}

void showLinks(Node *root) {
    for (
        Node *p = leftmost(root);
        p != NULL;
    ) {
        printf(
            "%2d: left=%s",
            p->data,
            p->lthread ? "THREAD " : "CHILD  "
        );

        if (p->left)
            printf("%d", p->left->data);
        else
            printf("NULL");

        printf(
            ", right=%s",
            p->rthread ? "THREAD " : "CHILD  "
        );

        if (p->right)
            printf("%d", p->right->data);
        else
            printf("NULL");

        putchar('\n');

        p = p->rthread
            ? p->right
            : leftmost(p->right);
    }
}

/* Ignore thread links to avoid cycles/double-free. */

void freeThreadedTree(Node *p) {
    if (!p) return;

    if (p->lthread == 0)
        freeThreadedTree(p->left);

    if (p->rthread == 0)
        freeThreadedTree(p->right);

    free(p);
}

int main(void) {
    /* Ordinary tree before conversion:

              40
             /  \
           20    60
          /  \     \
        10   30     70
             /
            25
    */

    Node *root = create(40);

    root->left = create(20);
    root->right = create(60);

    root->left->left = create(10);
    root->left->right = create(30);

    root->left->right->left = create(25);
    root->right->right = create(70);

    convertToInorderThreads(root);

    printf("Inorder: ");
    inorderNoStack(root);

    printf("\nReverse: ");
    reverseInorderNoStack(root);

    printf("\n\nPointer map:\n");
    showLinks(root);

    freeThreadedTree(root);
    return 0;
}

Expected Output

Console output (short view)
Inorder: 10 20 25 30 40 60 70
Reverse: 70 60 40 30 25 20 10

Pointer map:
10: left=THREAD NULL, right=THREAD 20
20: left=CHILD  10, right=CHILD  30
25: left=THREAD 20, right=THREAD 30
30: left=CHILD  25, right=THREAD 40
40: left=CHILD  20, right=CHILD  60
60: left=THREAD 40, right=CHILD  70
70: left=THREAD 60, right=THREAD NULL

C Program Explained in Simple Steps

  1. create(): Allocates a new regular node with two initially empty child pointers.
  2. addThreads(): Walks the ordinary tree in Inorder and connects missing left/right pointers to their predecessor/successor.
  3. leftmost() / rightmost(): Follow only real child links, never threads.
  4. inorderNoStack(): Uses right-thread shortcuts or the leftmost node of a real right subtree.
  5. reverseInorderNoStack(): Uses left-thread shortcuts or the rightmost node of a real left subtree.
  6. freeThreadedTree(): Traverses only child links to free each node exactly once.

How to Run the C Program on Windows

Save the code as threaded_binary_tree_ch68.c. With GCC installed, open PowerShell in the same folder and run:

PowerShell
gcc -std=c11 -Wall -Wextra -pedantic threaded_binary_tree_ch68.c -o threaded_binary_tree_ch68

.\threaded_binary_tree_ch68.exe
12 / Efficiency and trade-offs

Time and Space Complexity of Threaded Binary Tree

Operation Time Extra Space
Convert ordinary tree into Inorder threads (shown code) O(n) O(h) recursion stack
Forward Inorder traversal after threading O(n) O(1)
Reverse Inorder traversal after double threading O(n) O(1)
Stored nodes and thread tags — O(n) total node storage

Here n is the number of real nodes, and h is the tree height. A full traversal still visits every node, so it cannot take less than O(n) time. The improvement is that later Inorder walks do not need an auxiliary stack.

Advantages of Threaded Binary Trees

  • Can reuse NULL child pointers for helpful navigation links.
  • Forward Inorder traversal can avoid recursion and an explicit stack.
  • Double-threaded trees support reverse Inorder traversal as well.
  • Useful for repeated traversal in some pointer-based applications.

Disadvantages of Threaded Binary Trees

  • Need extra tag bits to distinguish children from threads.
  • Insertion and deletion may require carefully updating neighbouring threads.
  • Preorder and Postorder variants need different navigation logic.
  • Threading does not automatically balance a tree or speed up every search.
13 / Comparison

Difference Between Binary Tree and Threaded Binary Tree

Feature Ordinary Linked Binary Tree Inorder Threaded Binary Tree
Missing child link NULL May become predecessor/successor thread
Tag needed? Usually not Yes, to identify child versus thread
Inorder traversal Commonly recursion or stack No stack/recursion needed after threading
Extra navigation Only child pointers Child pointers plus traversal shortcuts
Updates Maintain child links Maintain child links and affected threads
Full traversal time O(n) O(n)
14 / Exam mistakes

Common Mistakes in Threaded Binary Tree Questions

  1. Calling every pointer a thread: Only missing child links are replaced. Real child links must remain real.
  2. Mixing predecessor and successor: For Inorder, the left thread points backward; the right thread points forward.
  3. Ignoring lthread/rthread: Recursing along a thread as if it were a child may create cycles.
  4. Assuming threading changes Inorder: It changes pointers, not the original traversal order.
  5. Claiming O(1) build space in this code: Construction uses recursive calls; only the final threaded traversal has O(1) auxiliary space.
  6. Following the same algorithm for Postorder: Order-specific successor navigation can be more complicated.
  7. Freeing through threads: Threads can lead back to existing nodes; only true child links should be recursively freed.
15 / Student questions

FAQs on Threaded Binary Tree in Data Structure

1. What is a Threaded Binary Tree?

It is a Binary Tree that replaces selected NULL child pointers with traversal-based links called threads, often to an Inorder predecessor or successor.

2. What are the main types of Threaded Binary Trees?

Left-threaded, right-threaded and double-threaded trees. Threading can also be designed for Inorder, Preorder or Postorder traversal.

3. What is a double-threaded Binary Tree?

It can store predecessor threads in missing left pointers and successor threads in missing right pointers. Flags identify which links are threads.

4. Why do we use lthread and rthread flags?

They distinguish an actual child link from a traversal shortcut, preventing incorrect traversal and memory handling.

5. Can we perform Inorder Traversal without recursion?

Yes. After constructing a suitable Inorder-threaded tree, follow the successor threads or the leftmost node of real right subtrees, using O(1) extra space.

6. Does a Threaded Binary Tree improve search complexity?

Not automatically. Threads primarily support traversal navigation; they do not by themselves impose a search ordering or keep the tree balanced.

7. Are external/dummy nodes and threads the same thing?

No. Extended Binary Trees add special external nodes at missing links. Threaded Binary Trees use missing pointer fields to reference actual predecessor/successor nodes or NULL/sentinels.

16 / One-minute revision

Threaded Binary Tree Quick Revision Notes

  • Purpose: Use missing child pointers as useful traversal links.
  • Left thread: Inorder predecessor in a left-threaded Inorder design.
  • Right thread: Inorder successor in a right-threaded Inorder design.
  • Single: One direction; Double: Both directions.
  • lthread / rthread: Our code uses 0 = child and 1 = thread.
  • Forward Inorder: 10, 20, 25, 30, 40, 60, 70.
  • Reverse Inorder: 70, 60, 40, 30, 25, 20, 10.
  • Traversal: O(n) time and O(1) extra space after threading.
  • Construction: O(n) time; recursive code uses O(h) extra stack space.
  • Key warning: Never treat a thread as a real child edge.

Conclusion

A Threaded Binary Tree does not add extra ordinary children. Instead, it uses missing pointer fields to link nodes in a useful traversal order. The simplest example is an Inorder-threaded tree: its right threads can take us to the next Inorder node, and its left threads can take us to the previous one.

To understand the topic, first draw a normal tree, write its Inorder sequence, and identify every NULL child position. Then add the correct threads one by one. This method makes even the pointer-based C program much easier to follow.

Chapter 68 · Original examples and diagrams for learning Data Structures.

Tags

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Join Telegram Exam updates and free resources