Fact-checked by Grok 2 weeks ago

Binary tree

A binary tree is a fundamental hierarchical data structure in consisting of a of , where each contains a and at most two children, referred to as the left and right subtrees. The structure is either empty (with no nodes) or comprises a root connected to two disjoint binary subtrees, enabling recursive organization of . This design allows for efficient representation of relationships where order matters, such as in searching or sorting algorithms, and forms the basis for more specialized variants. Binary trees exhibit various structural properties that define their performance and utility. A full binary tree requires every to have exactly zero or two children, eliminating nodes with a single child to maintain balance in certain operations. In contrast, a complete binary tree fills s from left to right level by level, optimizing space usage in array-based implementations like heaps. Binary search trees (BSTs) impose an ordering constraint, where all values in the left subtree are less than the root and those in the right subtree are greater, facilitating logarithmic-time search, insertion, and deletion operations. Degenerate cases, resembling linked lists, occur when each has only one child, leading to linear performance akin to arrays. The versatility of binary trees underpins numerous applications across domains. They are essential in implementing efficient search mechanisms, such as in databases and file systems for quick hierarchical lookups. Binary search trees enable dynamic data management with average O(log n) complexity for core operations, making them ideal for sorted collections and features. Heaps, a type of complete binary tree, support priority queues used in algorithms like Dijkstra's shortest path or scheduling tasks. Additionally, expression trees represent mathematical or syntactic structures, aiding in compilers and evaluating arithmetic operations recursively.

Definitions

Recursive definition

A binary tree can be defined recursively as a data structure that is either empty or consists of a root node together with a left subtree and a right subtree, where each subtree is itself a binary tree. This recursive structure captures the self-similar nature of binary trees, enabling them to grow to arbitrary depth by repeatedly applying the definition to the subtrees. Formally, the set T of binary trees satisfies the recursive equation: T = \emptyset \cup \{ \text{root} \times T \times T \}, where \emptyset denotes the empty tree, the root is a node, and the Cartesian products represent the left and right subtrees. This definition permits nodes to have zero, one, or two children, depending on whether the subtrees are empty or non-empty. A variant known as a full binary tree imposes stricter recursive rules, where the base case is a single (a with zero children), and the recursive case requires a with exactly two non-empty full subtrees, ensuring every internal has precisely two children. In contrast, an extended binary tree (or general binary tree allowing nodes) relaxes this by permitting subtrees to be empty in the recursive step, thus allowing nodes with one . For example, consider a binary tree with root node A, a left subtree consisting of node B (a leaf), and an empty right subtree; this unfolds recursively as the left subtree of A satisfying the base case for B, while the right satisfies the empty case, demonstrating a node with one child.

Graph-theoretic definition

In graph theory, a binary tree is a finite rooted directed acyclic graph in which the root node has indegree 0, every non-root node has indegree exactly 1, and every node has outdegree at most 2. The directed edges point from parent nodes to their children, ensuring the structure is connected in the underlying undirected graph and free of directed cycles. This formalization captures the hierarchical organization without allowing loops or multiple paths between nodes. In an ordered binary tree, the two possible outgoing edges from any are distinguished as the left child and right child, imposing a linear on siblings. Unordered binary trees, by contrast, do not distinguish between left and right, treating the children as an unlabeled set. The constraints ensure that leaves—nodes with outdegree 0—terminate branches, while internal nodes (non-leaves except possibly the ) have outdegree 1 or 2 and receive exactly one incoming edge, except for the . This graph-theoretic perspective provides a rigorous for analyzing trees using tools from , such as and properties, distinct from recursive constructions. For illustration, consider a small ordered tree with four nodes: a r connected to left a (a ) and right b, where b connects to its left c (a ). The directed edges are r \to a (left), r \to b (right), and b \to c (left), satisfying indegree and outdegree limits with no cycles.
      r
     / \
    a   b
       /
      c

Properties

Structural properties

A binary tree consists of connected by edges, where each except the has exactly one , ensuring a hierarchical without multiple incoming connections. The subtrees rooted at the left and right children of any are disjoint, meaning they share no in common, which maintains the tree's partitioned organization. The left and right subtrees of a node are structurally independent, allowing each to develop its own configuration without influencing the other, though they may exhibit mirroring symmetries in certain tree variants. In any binary tree with n nodes, the number of edges is exactly n - 1, as each non-root node contributes one incoming edge, forming a connected acyclic graph. For a full binary tree, where every node has either zero or two children, the total number of nodes n satisfies n = 2l - 1, with l denoting the number of leaves; this relation arises because the number of leaves is one more than the number of internal nodes, as each internal node has two children and the tree has n-1 edges. Binary trees contain no , a property proven by the uniqueness of paths from the : suppose a exists; then any on the cycle would have two distinct paths from the root (one direct and one via the cycle), contradicting the single-parent rule that ensures exactly one path to each node.

Height and size relationships

In binary trees, the height h of a tree is defined as the number of edges on the longest path from the node to a leaf node. The depth of a node is the number of edges on the path from the to that , with the at depth 0. For a binary tree with n nodes, the minimum height is achieved when the tree is as balanced as possible, such as in a complete binary tree, where h \geq \log_2(n+1) - 1. This bound ensures the tree fills levels from left to right before advancing to deeper levels. In contrast, the maximum height occurs in a degenerate binary tree, resembling a linear chain, where h = n - 1. Given a fixed height h, a binary tree can hold a maximum of $2^{h+1} - 1 nodes, which is the case for a full binary tree where every level is completely filled and every node has either zero or two children. The minimum number of nodes for h is h + 1, occurring in a skewed with a single path from to . Nodes in the tree are distributed across levels indexed from 0 (root) to h, where the maximum number of nodes at level k is $2^k. These relationships between and directly influence the of operations. For instance, searching for a requires traversing at most h edges in the worst case, leading to O(h) time, which underscores the importance of minimizing to improve in applications like search .

Types

Complete and perfect binary trees

A full binary tree, also known as a proper binary tree or 2-tree, is defined as a binary tree in which every has either zero or two children, with no nodes having exactly one child. This structure ensures that all internal nodes branch fully, leading to a strict alternation between internal nodes and leaves. A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes in the last level are as far to the left as possible. This filling pattern from left to right makes complete binary trees particularly suitable for implementing priority queues like heaps, where the shape facilitates efficient operations. Complete binary trees can have nodes with one child only in the last level, distinguishing them from full binary trees. A perfect binary tree is a special case where all levels are completely filled, with every internal node having exactly two children and all leaves at the same depth. For a perfect binary tree of height h (where the root is at height 0), the total number of nodes is given by the formula $2^{h+1} - 1. Every perfect binary tree is both full and complete, but the converse does not hold. To illustrate the differences, consider simple textual representations: Full binary tree example (all nodes have 0 or 2 children, but levels may not be filled evenly):
    A
   / \
  B   C
 / \
D   E
This tree is full but neither complete nor perfect due to uneven level filling. Complete binary tree example (levels filled left-to-right, last level partial):
      A
     / \
    B   C
   / \ /
  D  E F
Here, the last level has nodes D, E, and F filled from the left, making it complete but not perfect. Perfect binary tree example (all levels fully filled):
      A
     / \
    B   C
   / \ / \
  D  E F  G
This structure has all seven nodes at heights 0 through 2, fully populating each level. A key property of complete binary trees is their with -based , where s are indexed sequentially in level , allowing parent- access via simple arithmetic (e.g., for a at i, its left is at $2i + 1 and right at $2i + 2). This representation minimizes space overhead from pointers, though detailed implementations are discussed in contexts.

Balanced binary trees

A balanced binary tree is defined as a binary tree in which the heights of the left and right subtrees of every differ by at most one. This property ensures that the overall height of the tree remains logarithmic in the number of nodes, preventing degeneration into a linear structure. Self-balancing binary trees automatically maintain this balance through rebalancing operations triggered by insertions and deletions, guaranteeing efficient performance. AVL trees, named after their inventors Georgy Adelson-Velsky and Evgenii Landis, were the first self-balancing binary search trees, introduced in their 1962 paper on information organization algorithms. They enforce a strict balance factor of at most one for every node by performing single or double rotations after structural modifications to restore height equilibrium. This rigorous maintenance results in a tree height bounded by approximately 1.44 log₂(n + 2) - 0.328 for n nodes, providing worst-case O(log n) time for key operations. Red-black trees offer a more relaxed balancing approach, originally described by in 1972 as symmetric binary B-trees, later formalized with color attributes. Each is colored , with properties ensuring no two red nodes are adjacent and that all paths from a node to its leaves contain the same number of black nodes. These rules limit the height to at most twice the height of a perfectly balanced tree, yielding O(log n) operations while allowing fewer rotations than AVL trees during rebalancing. Splay trees, invented by Daniel Sleator and in 1985, achieve balance through rather than strict height constraints. Upon accessing a , it is "splayed" to the root via a series of rotations, promoting frequently accessed elements and ensuring that any sequence of m operations takes O(m log n + n log n) time in the worst case. This self-adjusting mechanism adapts to access patterns without explicit balance factors, often outperforming other balanced trees for non-uniform distributions. The primary benefit of balanced binary trees like AVL, red-black, and splay trees is their assurance of O(log n) worst-case or amortized for insertions, deletions, and searches, in contrast to the potential O(n) degradation in unbalanced binary search trees. This efficiency is crucial for applications requiring dynamic , such as databases and file systems, where maintaining logarithmic access times scales with large datasets.

Combinatorics

Enumeration of binary trees

The enumeration of binary trees typically focuses on unlabeled plane binary trees, which are rooted structures where the order of subtrees matters, distinguishing between left and right ren, and nodes are indistinguishable except by their positions in the hierarchy. The number of such distinct binary trees with exactly n nodes is given by the nth C_n = \frac{1}{n+1} \binom{2n}{n}. This count arises from considering the root node and partitioning the remaining n-1 nodes between the left and right subtrees. Based on the recursive definition of binary trees, the enumeration satisfies the T(n) = \sum_{i=0}^{n-1} T(i) \, T(n-1-i) for n \geq 1, with base cases T(0) = 1 (empty tree) and T(1) = 1 (single root node). For example, with n=3 nodes, there are C_3 = 5 possible shapes: one where the root has two children; two where the root has only a left child that itself has one child (either left or right); and two symmetric cases where the root has only a right child that itself has one child (either left or right). These enumerative results have applications in and , particularly in counting the possible parse trees for expressions in context-free grammars, where binary trees model precedence and associativity. They also inform the design and analysis of networks, where the structural variety of binary trees helps enumerate decision paths in parallel comparison-based architectures.

Catalan numbers in binary trees

The nth is defined as C_n = \frac{1}{n+1} \binom{2n}{n}, where \binom{2n}{n} denotes the . This sequence arises in numerous combinatorial contexts, with C_0 = 1, C_1 = 1, C_2 = 2, C_3 = 5, and so on. In the context of trees, the nth C_n enumerates the number of distinct rooted plane trees with n+1 leaves, where each internal node has exactly two children. Equivalently, C_n counts the number of such trees with n internal nodes. This interpretation highlights the recursive structure of trees: a tree with n internal nodes consists of a connected to a left subtree with k internal nodes and a right subtree with n-1-k internal nodes, for k = 0 to n-1, leading to the recurrence C_n = \sum_{k=0}^{n-1} C_k C_{n-1-k} with C_0 = 1. The ordinary generating function for the Catalan numbers is C(x) = \sum_{n=0}^{\infty} C_n x^n = \frac{1 - \sqrt{1 - 4x}}{2x}, which satisfies the functional equation C(x) = 1 + x C(x)^2 derived from the recursive decomposition of binary trees. This equation mirrors the way a binary tree is formed by attaching two subtrees to the root, providing a generating function approach to count the trees. A standard proof of the Catalan number formula in this setting relies on a bijection between rooted plane binary trees with n+1 leaves and valid sequences of n pairs of balanced parentheses. The mapping proceeds recursively: the empty tree corresponds to the empty sequence; otherwise, the sequence for a tree is the left subtree's sequence enclosed in parentheses, followed by the right subtree's sequence. This bijection preserves the recursive structure and directly yields the count C_n, as the number of valid parenthesis sequences is also given by the Catalan formula. An analogous bijection exists with Dyck paths of semilength n, which can be interpreted as the "heights" traversed in a tree's structure, further confirming the enumeration. An important extension is that C_n also counts the number of full binary trees (where every node has either zero or two children) with exactly $2n+1 nodes, since such trees have n internal nodes and n+1 leaves. This provides a foundational tool for enumerating binary trees, as discussed in the broader enumeration section. The Catalan numbers are named after the Belgian mathematician , who first studied them in 1838 while investigating combinatorial problems related to successive roots and combinations. Although the explicit connection to binary trees emerged later, combinatorial interpretations including tree structures were recognized in 19th-century works building on these foundations.

Representations

Node-based storage

In node-based storage, binary trees are implemented as a collection of dynamically allocated s linked via pointers, allowing for flexible representation of arbitrary structures. Each typically stores the associated value along with two pointers: one to the left and one to the right , enabling the of the . This structure supports pointers for leaves or missing children, ensuring that every has at most two children. Optionally, an additional parent pointer can be included in each to simplify navigation and operations such as deletion in bidirectional traversal scenarios. Memory management in this representation relies on dynamic allocation for each node, which incurs overhead beyond the data itself—typically the space for two (or three) pointers, each requiring 4 or 8 bytes depending on the system architecture. This pointer overhead can represent a significant portion of memory usage, especially for trees with small data elements, but it avoids wasting space on non-existent nodes unlike contiguous representations. Dynamic allocation, often handled by language runtimes or manual calls in languages like C, allows the tree to grow or shrink as needed without predefined size limits. However, frequent allocations and deallocations can lead to external memory fragmentation, where free memory becomes scattered in small blocks unsuitable for larger requests. The primary advantages of node-based storage lie in its adaptability to unbalanced or irregular tree shapes, making it ideal for scenarios where the tree structure evolves unpredictably. Insertion and deletion operations are efficient and intuitive, involving only pointer adjustments rather than shifting elements, which supports O(1) local changes after locating the position. This flexibility is particularly valuable in general-purpose applications, such as implementing binary search trees for dynamic sets or expression trees in compilers. Despite these benefits, node-based storage has notable drawbacks, including reduced efficiency due to pointer chasing, where traversing the requires jumping between non-contiguous locations, leading to frequent cache misses and slower access times compared to contiguous alternatives. The additional pointer storage also increases overall , and in unbalanced trees, can degrade to linear time in the worst case, mimicking a . To illustrate the node definition, the following shows a basic class in a style, commonly used in implementations with languages supporting object-oriented or :
class [Node](/page/Node) {
    [data](/page/Data)  // The [value](/page/Value) stored in the [node](/page/Node)
    left: [Node](/page/Node) | [null](/page/Null)  // Pointer to left [child](/page/Child)
    right: [Node](/page/Node) | [null](/page/Null)  // Pointer to right [child](/page/Child)
    // Optional: [parent](/page/Parent): [Node](/page/Node) | [null](/page/Null)  // Pointer to [parent](/page/Parent) [node](/page/Node)

    constructor([value](/page/Value)) {
        this.[data](/page/Data) = [value](/page/Value)
        this.left = [null](/page/Null)
        this.right = [null](/page/Null)
        // this.[parent](/page/Parent) = [null](/page/Null)
    }
}
This representation is a staple for structures in binary trees, contrasting with array-based storage that suits denser, complete trees but lacks the same structural versatility.

Array-based storage

Array-based storage represents a binary tree using a single contiguous array, eliminating the need for explicit pointers between s and making it particularly suitable for complete binary trees where nodes are filled level by level from left to right. A common convention places the root at 1 (with 0 often left unused as a ), the left of a at i at $2i, and the right at $2i + 1; alternatively, 0-based indexing places the root at 0, left at $2i + 1, and right at $2i + 2. This indexing allows direct computation of parent-child relationships using simple arithmetic: for 1-based, the parent of a at i (for i > 1) is at \lfloor i/2 \rfloor; for 0-based, it is at \lfloor (i - 1)/2 \rfloor. The is O(n) for a with n s, as each occupies one slot without additional overhead for pointers, assuming the is sized appropriately for the complete structure. This contiguous layout enhances efficiency, enabling faster access patterns in compared to pointer-based methods, and supports constant-time computation for locating children or parents. However, this representation assumes the is complete or nearly complete; sparse trees waste space in unused positions, and fixed-size s limit dynamic without resizing, which can introduce overhead. For insertion in a complete binary tree, a new node is added at the next available position in level order (the end of the current ), maintaining the complete property, after which adjustments like heapifying up may be applied if the tree enforces additional ordering (e.g., in binary heaps). Consider a small complete binary tree with value 1, left 2, right 3, and 2 having a left 4. This is represented in the as [-, 1, 2, 3, 4], where the leading - denotes the unused 0, and positions 1 through 4 hold the node values in level order.

Encodings

Succinct encodings

Succinct encodings for binary trees aim to represent the structure of an n-node ordered binary tree using 2n + bits of space, approaching the information-theoretic lower bound of approximately 2n bits needed to distinguish among the C_n of possible structures, in contrast to the Θ(n log n) bits required by conventional node-based storage that allocates words for left and right child pointers per node. One foundational approach is the representation, which captures the tree's via a depth-first traversal. During traversal, an opening parenthesis '(' is recorded upon descending to a subtree, and a closing parenthesis ')' upon ascending from a ; leaves contribute a single pair '()'. This yields exactly 2n bits for n , as each corresponds to one opening and one closing parenthesis. For instance, a with a left and a right that itself has left and right encodes as "(()(()()))", where the inner "()" (after the initial open) denotes the left , and "(()())" the right subtree. To enable efficient querying on this bit sequence, succinct encodings incorporate and select data structures. The operation computes the number of opening parentheses up to a given position, while select identifies the position of the k-th opening parenthesis. Preprocessing the BP sequence with o(n) extra bits—typically O(n log log n / log n)—allows both operations in O(1) time, supporting key tree navigations such as finding a node's , left or right , depth, or subtree size in constant time. These encodings find application in succinct data structure libraries, such as the Succinct Data Structure Library (SDSL), where they enable compact storage and fast access for large-scale tree-based indexes in bioinformatics and .

Encoding general trees as binary trees

One common technique for encoding general ordered trees, including m-ary trees where m can vary, as binary trees is the first-child/next-sibling representation, also known as the left-child/right-sibling or Knuth transform. In this method, each in the binary tree structure uses its left pointer to reference the first child of the corresponding in the original general , and its right pointer to reference the next in the ordered list of children. This approach requires only two pointers per , providing O(1) additional space overhead beyond the original tree's storage, regardless of the m, by siblings into a via right pointers. The method was proposed by in the 1960s to enable uniform algorithmic treatment of multi-way trees using tree operations, as detailed in his seminal work on fundamental algorithms. It preserves the ordered structure of children in the general tree, maintaining ancestry relationships through the left-child chains, which form the subtrees, while the right-sibling links ensure traversal follows the original sibling order. This encoding is reversible, allowing reconstruction of the original general tree from the binary representation without loss of information. A key advantage is the ability to apply standard binary tree traversal and manipulation algorithms—such as in-order or level-order traversals—to general trees, facilitating implementation in systems optimized for binary structures and reducing code complexity for handling variable-arity nodes. For instance, depth-first traversal in the encoded binary tree can mimic traversal of the original tree by following left subtrees (children) before right links (siblings). To illustrate, consider a simple ternary tree with root A having children B, C, and D, where B has child E, C has children F and G, and D is a leaf. In the binary encoding:
  • A's left points to B (first child), and B's right points to C (B's next sibling), C's right points to D (C's next sibling), D's right is null.
  • B's left points to E (B's first child), E's right is null.
  • C's left points to F (C's first child), F's right points to G (F's next sibling), G's right is null.
  • D's left is null ().
This remapping transforms the multi-child structure into a binary tree where left edges represent parent-child ancestry and right edges represent adjacency, fully preserving the original and .

Operations

Insertion and deletion

Insertion in a binary tree, particularly in the context of binary search trees (BSTs), involves adding a new while preserving the tree's and . For a BST, the algorithm starts at the and compares the new with the current 's , traversing left if smaller or right if larger, until reaching a child pointer where the new is attached as a . This recursive placement ensures the BST property: all s in the left subtree have keys less than the , and all in the right subtree have keys greater. The takes O(h) time, where h is the tree's height, which is O(log n) on average for balanced trees but O(n) in the worst case for skewed ones. For an empty tree, insertion creates the new node as the . for BST insertion, adapted from standard recursive implementations, is as follows:
[function](/page/Function) insert([root](/page/Root), key):
    if [root](/page/Root) is [null](/page/Null):
        return new [Node](/page/Node)(key)
    if key < [root](/page/Root).key:
        [root](/page/Root).left = insert([root](/page/Root).left, key)
    elif key > [root](/page/Root).key:
        [root](/page/Root).right = insert([root](/page/Root).right, key)
    return [root](/page/Root)
This approach handles duplicates by either ignoring them or placing them in a specified subtree, depending on the . Deletion in a BST removes a with a given while maintaining the search , involving three cases based on the number of . If the node is a (no children), it is simply removed by setting its parent's pointer to . For a node with one child, the child replaces the node directly, bypassing it in the . In the case of two children, the node's value is replaced with its inorder successor (the minimum value in the right subtree), and then the successor node—which has at most one child—is deleted. This successor replacement preserves the BST order. The remains O(h), similar to insertion. Pseudocode for BST deletion illustrates these cases:
function delete(root, key):
    if root is null:
        return root
    if key < root.key:
        root.left = delete(root.left, key)
    elif key > root.key:
        root.right = delete(root.right, key)
    else:
        # Node found
        if root.left is null:
            return root.right
        elif root.right is null:
            return root.left
        else:
            successor = findMin(root.right)
            root.key = successor.key
            root.right = delete(root.right, successor.key)
    return root

function findMin(node):
    while node.left is not [null](/page/Null):
        node = node.left
    return node
Root deletion requires updating the root reference to the appropriate replacement. Edge cases include attempting to delete from an empty tree (no operation) or handling equal keys consistently with insertion policy. In self-balancing binary trees like , insertion and deletion may disrupt balance, addressed by rotations to keep subtree heights differing by at most one. After modification, balance factors are checked along the path; if exceeding 1 in , single (left or right) or double rotations are applied at the lowest unbalanced ancestor. These rotations, such as right rotation for left-heavy subtrees, restore balance in O(1) additional time per operation, ensuring amortized O(log n) complexity. The was introduced in a seminal 1962 paper by Adelson-Velsky and Landis.

Traversal methods

Binary tree traversal refers to the process of visiting each in the tree exactly once in a systematic manner, enabling operations such as , , or processing node data. These methods are fundamental for analyzing and manipulating binary trees, with algorithms typically achieving time , where n is the number of nodes, since each node is processed once. Space varies by approach, often O(h) for recursive methods, where h is the tree , due to the call or explicit data structures like stacks or queues.

Depth-First Traversals

Depth-first traversals (DFS) explore as far as possible along each branch before , encompassing three primary variants: , inorder, and postorder. These can be implemented recursively or iteratively using a , with recursive versions being simpler but consuming O(h) space in the worst case for skewed trees. Iterative versions mimic explicitly with a , also requiring O(h) space. Preorder traversal visits the node first, followed by the left subtree, then the right subtree. This order is useful for creating a copy of the tree or serializing it to prefix notation. The recursive is as follows:
function preorder([root](/page/Root)):
    if [root](/page/Root) is [null](/page/Null):
        return
    visit [root](/page/Root)
    preorder([root](/page/Root).left)
    preorder([root](/page/Root).right)
An iterative version uses a to push the , then repeatedly pops a node, visits it, and pushes its right and left children in reverse order to maintain the traversal sequence. Inorder traversal processes the left subtree, then the root, followed by the right subtree. In a , this yields nodes in sorted (non-decreasing) order. The recursive is:
function inorder(root):
    if root is null:
        return
    inorder(root.left)
    visit root
    inorder(root.right)
Iterative inorder uses a to simulate the , pushing nodes while traversing left and popping to visit when no left child exists, then moving right. Postorder traversal visits the left subtree, then the right, and finally the root. This is particularly useful for operations requiring processing of children before parents, such as computing subtree sizes or deleting trees. The recursive is:
function postorder(root):
    if root is null:
        return
    postorder(root.left)
    postorder(root.right)
    visit root
Iterative postorder is more complex, often using two s—one for traversal and one for output—or a single stack with additional tracking of visited children.

Breadth-First Traversal

Breadth-first traversal, also known as level-order traversal, visits nodes level by level, starting from the and proceeding left to right across each level. This uses a to enqueue the , then repeatedly dequeues a node, visits it, and enqueues its children. The is:
function levelOrder([root](/page/Root)):
    if [root](/page/Root) is [null](/page/Null):
        return
    [queue](/page/Queue) = new [Queue](/page/Queue)()
    [queue](/page/Queue).enqueue([root](/page/Root))
    while [queue](/page/Queue) is not empty:
        current = [queue](/page/Queue).dequeue()
        visit current
        if current.left is not [null](/page/Null):
            [queue](/page/Queue).enqueue(current.left)
        if current.right is not [null](/page/Null):
            [queue](/page/Queue).enqueue(current.right)
This method requires O(w) space, where w is the maximum width of the tree (number of nodes at the widest level), in addition to O(n) time. It is distinct from DFS in that it prioritizes shallower nodes over deeper ones.

Morris Traversal

Morris traversal provides an in-order traversal using O(1) extra space by temporarily modifying the tree's structure through "threading"—linking nodes to their in-order successors via unused right-child pointers—then restoring the links during traversal. Introduced by J. H. Morris, it achieves O(n) time by visiting each node a constant number of times on average, though worst-case analysis shows up to O(n) edge traversals due to pointer adjustments. The algorithm initializes with the leftmost node, finds successors by following right pointers until null, threads them, visits, and unthreads upon backtracking. Pseudocode for Morris in-order is:
function morrisInorder([root](/page/Root)):
    current = [root](/page/Root)
    while current is not [null](/page/Null):
        if current.left is [null](/page/Null):
            visit current
            current = current.right
        else:
            predecessor = current.left
            while predecessor.right is not [null](/page/Null) and predecessor.right != current:
                predecessor = predecessor.right
            if predecessor.right is [null](/page/Null):
                predecessor.right = current  // thread
                current = current.left
            else:
                predecessor.right = [null](/page/Null)  // unthread
                visit current
                current = current.right
This method is non-recursive and avoids stacks or queues but alters the tree temporarily, which may not suit immutable structures.

Applications

In data structures

Binary search trees (BSTs) are a fundamental extension of binary trees used for organizing and storing ordered sets of s, where each node contains a and the keys in the left subtree are less than the node's , while those in the right subtree are greater. This structure enables efficient searching, insertion, and deletion operations, with an average of O(\log n) for balanced trees, making it suitable for dynamic in applications requiring ordered access. Heaps, specifically binary heaps, represent another key application of binary trees as complete binary trees that satisfy the heap property: in a min-heap, each parent is less than or equal to its children, and in a max-heap, it is greater than or equal to them. This structure underpins priority queues, allowing efficient extraction of the minimum or maximum element in O(\log n) time and insertion in O(\log n) time, which is essential for scheduling and resource allocation tasks. The binary heap was originally introduced as part of the algorithm. Tries, or prefix trees, can be implemented as binary trees when handling or bit-level representations of strings, where each represents a bit and branches correspond to 0 or 1 values. This specialization facilitates fast prefix-based searches and is particularly useful for storing and retrieving strings or keys with common prefixes, such as in implementations or systems, with search times proportional to the key length rather than the total number of keys. The trie concept was first described in the context of file searching with variable-length keys. Expression trees model arithmetic or logical expressions as binary trees, with operators as internal nodes and operands as leaves, enabling systematic evaluation, parsing, and optimization in design. For instance, the expression (a + b) \times c is represented with \times as the , the subexpression (a + b) in the left subtree, and c in the right. This structure supports postfix or prefix traversal for and is integral to syntax analysis in programming languages. BSTs are commonly employed in dictionary implementations for maintaining sorted word lists with fast lookups, while heaps serve as queues in algorithms like Dijkstra's shortest path, where they efficiently manage node during . Balanced variants, such as AVL trees or red-black trees, enhance BSTs and heaps by ensuring O(\log n) worst-case performance through rotations or color adjustments.

In algorithms and computing

Binary trees play a pivotal role in various algorithms, enabling efficient decision-making, optimization, and in computational problems. In algorithms, leverages a (BST) by inserting elements into the tree structure, which organizes them based on comparisons, followed by an in-order traversal to retrieve the elements in sorted order. This approach achieves an average of O(n log n) for n elements when the tree remains balanced, making it suitable for scenarios where dynamic insertion during is beneficial. The BST for such traces back to early implementations in the , as described in foundational work on ordered binary trees. Huffman coding utilizes binary trees to construct optimal prefix-free codes for data compression, minimizing the average length of encoded symbols based on their frequencies. The algorithm builds a binary tree where leaf nodes represent symbols, and internal nodes merge the two lowest-frequency subtrees iteratively, assigning shorter codes to more frequent symbols along the paths from the root. This results in an encoding that approaches the theoretical limit for , widely adopted in standards like and . The method was originally developed by in 1952, revolutionizing applications. In game theory and artificial intelligence, binary trees can model decision processes with binary branching factors, such as simple two-choice scenarios. For two-player zero-sum games like chess, which feature higher branching factors, general trees represent game states with branches for possible moves, and the minimax algorithm recursively evaluates these trees to select the move that minimizes the maximum possible loss assuming optimal opponent play. Leaf nodes are scored based on outcomes, and values propagate upward: maximizer nodes (one player) choose the highest value, while minimizer nodes (opponent) select the lowest. This search, as applied in chess AI, enables strategic depth but requires pruning techniques like alpha-beta to manage exponential growth. The minimax theorem underpinning this was formalized by John von Neumann in 1928. Binary trees facilitate divide-and-conquer strategies in , exemplified by parallel , where the naturally maps to a binary tree of tasks. The array is divided into halves recursively, forming a balanced binary tree of subproblems sorted in parallel across processors, then merged bottom-up. This achieves O(log n) depth for parallelism, with total work O(n log n), ideal for distributed systems. Early parallel formulations built on von Neumann's 1945 , with efficient implementations like Cole's 1988 algorithm optimizing load balance on PRAM models. In , binary decision trees serve as classifiers by recursively partitioning data based on feature thresholds, forming a binary tree where each internal tests a condition, left branches for true, and right for false, until leaves assign class labels. This structure enables interpretable models for tasks, such as spam detection, by selecting splits that maximize information gain. The , introduced by J. Ross Quinlan in 1986, pioneered this approach using to build such trees from training data. The balanced height of binary trees is crucial for achieving O(n log n) time complexity in algorithms reliant on logarithmic search or traversal depths, such as in dynamic sets or sorting networks. Self-balancing variants maintain height at O(log n) through rotations or restructuring after insertions/deletions, ensuring worst-case efficiency and preventing degeneration to linear chains. This property underpins the scalability of algorithms like those in search-heavy applications. AVL trees, the first such balanced binary search trees, were invented by G. M. Adelson-Velsky and E. M. Landis in 1962, enforcing balance factors to guarantee logarithmic height. Historically, binary trees emerged in early compilers during the 1950s and 1960s for and syntax analysis, representing expression trees and hierarchical program structures. They enabled efficient by modeling recursive descent and operator precedence in languages like , forming the basis for syntax-directed translation. This use predated formal nomenclature but influenced compiler design, as seen in Irons' 1961 work on syntax-directed compilers.

References

  1. [1]
    Binary Trees - Stanford CS Education Library
    A binary tree is made of nodes, where each node contains a "left" pointer, a "right" pointer, and a data element. The "root" pointer points to the topmost node ...
  2. [2]
    [PDF] Data Structures What is a binary tree?
    • Binary tree - a finite set of elements that is either empty or partitioned into three disjoint sets, called the root, and the left and right subtrees. Page 2 ...
  3. [3]
    6. Trees
    May 31, 2022 · A binary tree is either an external node or an internal node attached to an ordered pair of binary trees called the left subtree and the right ...
  4. [4]
    Tree Data Structure
    A binary tree in which each node has exactly zero or two children is called a full binary tree. In a full tree, there are no nodes with exactly one child.
  5. [5]
    7.2. Binary Trees — CS3 Data Structures & Algorithms - OpenDSA
    A binary tree is made up of a finite set of elements called nodes. This set either is empty or consists of a node called the root together with two binary trees ...
  6. [6]
    [PDF] Trees & Binary Search Trees | CMSC 132 - UMD Computer Science
    Types of Binary Trees. • Degenerate. • Mostly 1 child/node. • Height = O(n) ... • http://btv.melezinek.cz/binary-search-tree.html. © Department of Computer Science ...
  7. [7]
    12.1. Binary Trees Chapter Introduction - OpenDSA
    Just a few examples of applications that trees can speed up include prioritizing jobs, describing mathematical expressions and the syntactic elements of ...
  8. [8]
    12.3. Binary Tree as a Recursive Data Structure - OpenDSA
    A binary tree is defined as either an empty tree or a node pointing to two binary trees, one its left child and the other its right child.
  9. [9]
    Binary Trees - CSE 143 - University of Washington
    Simple Tree. The binary tree has a very natural recursive definition that matches a tree of any height! A tree is one of two possibilities * An empty tree ...
  10. [10]
    [PDF] Binary Tree
    own. • Recursive definition: a binary tree is either the null/empty tree of a node that has two children that are binary trees (called subtrees).
  11. [11]
    [PDF] CMSC 420: Lecture 3 Rooted Trees and Binary Trees
    4: Binary trees: (a) standard definition, (b) full binary tree, (c) extended binary tree. Binary trees can be defined more formally as follows. First, an ...
  12. [12]
    [PDF] Induction and recursion - Kent
    Definition: The set of full binary trees can be defined recursively by these steps. BASIS STEP: There is a full binary tree consisting of only a single vertex r ...
  13. [13]
    [PDF] Recursive Definitions Recursion Recursively Defined Functions ...
    – The empty set * is an extended binary tree. – If T1,T2 are disjoint EBTs ... – A single node r is a full binary tree. • Note this is different from ...
  14. [14]
    [PDF] 3.1 Characterizations and Properties of Trees 3.2 Rooted Trees ...
    The left (right) subtree of a vertex v in a binary tree is the binary subtree spanning the left (right)-child of v and all of its descendants. Page 19. GRAPH ...Missing: theoretic | Show results with:theoretic
  15. [15]
    ADS Binary Trees
    9 Graph Theory · 9.1 Graphs - General Introduction · 9.1.1 Definitions · 9.1.2 ... 1 Definition of a Binary Tree. 🔗. An ordered rooted tree is a rooted tree ...
  16. [16]
    [PDF] CSC148 winter 2014 - recursive structures week 6
    binary tree traversals recursive tree class. 2/15. Page 3. recursion ... I Each non-root node has exactly one parent. I A path is a sequence of nodes ...
  17. [17]
    12.2. Binary Trees — OpenDSA Data Structures and Algorithms ...
    (Disjoint means that they have no nodes in common.) The roots of these subtrees are children of the root. There is an edge from a node to each of its children, ...
  18. [18]
    [PDF] 4.3 Binary Search Trees - cs.Princeton
    Use root of T2 as root with probability N2 / (N1 + N2), and recursively join left subtree of T2 with T1. Join. Merge T1 (of size N1) and T2 (of size N2) ...
  19. [19]
    [PDF] Module 6: Binary Trees - Jackson State University
    Each node (except the root node) in the tree has exactly one parent. In a tree of 'N' nodes, there will be exactly 'N-1' links. The “depth” (or equivalently ...
  20. [20]
    [PDF] Full and Complete Binary Trees
    Definition: a binary tree T is full if each node is either a leaf or possesses exactly two child nodes. Definition: a binary tree T with n levels is complete if ...
  21. [21]
    [PDF] Trees - Department of Computer Science
    (⇐) Suppose there is a unique path between u and v for any two vertices in V . Therefore, the graph is connected. We must show there is no cycles. Suppose there ...
  22. [22]
    Binary Trees - andrew.cmu.ed
    A binary tree is made of nodes, where each node contains a "left" reference, a "right" reference, and a data element.
  23. [23]
    [PDF] tree-notes.pdf
    (The derivation of this was courred in our binary heap lecture.) This is also the minimum height of a binary tree with n nodes! Max is (n-1). Page 6. Let's ...
  24. [24]
    Chapter 8: Trees
    Maximum and Minimum Height. Q: If a binary tree has n nodes, what is the maximum height it can be? A: n-1. Q: If a binary tree has n nodes, ...
  25. [25]
    [PDF] Binary Tree Properties & Representation - UF CISE
    Minimum number of nodes in a binary tree whose height is h. • At least one node at each of first h levels. minimum number of nodes is h.<|control11|><|separator|>
  26. [26]
    [PDF] Binary Trees ©David Gries, 2022 Table of contents - CS@Cornell
    A tree with the minimum number of nodes will have one node on each level. Example: the tree to the right has height 2 and 3 nodes. 2. Maximum number of nodes at ...
  27. [27]
    Data Structures: Lecture 8 - Texas Computer Science
    So a binary tree with n nodes has a height of h = floor (log2 n) (floor(n) means the closest integer less than or equal to n). How does this help us?
  28. [28]
    Full v.s. Complete Binary Trees
    A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.
  29. [29]
    CSC-416 Lecture Notes
    A complete binary tree can be stored in an array in breadth-first order. No links are necessary. A heap is a complete binary tree, in which each node ...
  30. [30]
    [PDF] Class Notes CS 3137 1 The Tree Data Model: Overview
    We can recursively define an Expresison Tree as: • An ET is a single node containing a numeric value. • An ET is a binary tree, whose root node is an operator ...<|control11|><|separator|>
  31. [31]
    [PDF] Topic 18 Binary Trees
    Definitions. A tree data structure. – one entry point, the root. – Each node is either a leaf or an internal node. – An internal node has 1 or more.
  32. [32]
    Trees
    Binary tree is a special kind of a tree in which nodes have at most 2 children (none or left-child only or right-child or both). When a tree of height d has all ...
  33. [33]
    [PDF] Page 1 of 5 5.2 Perfect Binary Trees Having introduced binary trees ...
    A recursive definition of a perfect binary tree is: 1. A single node with no children is a perfect binary tree of height h = 0,. 2. A perfect binary tree with ...
  34. [34]
    12.16. Array Implementation for Complete Binary Trees - OpenDSA
    1. An array can store the tree's data values efficiently, placing each data value in the array position corresponding to that node's position within the tree.
  35. [35]
    Review of Heaps and Array embedded trees
    Binary trees can be efficiently stored in arrays by using an encoding that stores tree elements at particular indexes in the array.
  36. [36]
    [PDF] Balanced tree - Cornell: Computer Science
    Here are two definitions: 1. A binary tree is height-balanced if for each node the heights of its subtrees differ by at most 1. (Remember,.
  37. [37]
    B-Trees: Efficient Database Indexing Structures - cs.wisc.edu
    B-Trees are self-balancing tree data structures that maintain sorted data and allow searches, sequential access, insertions, and deletions in logarithmic time.
  38. [38]
    CS106B More on Binary Trees - Stanford University
    Balanced BSTs support worst-case logarithmic insertion, search, and deletion operations. If we want to maintain a sorted vector or array, inserting a new ...
  39. [39]
    [PDF] An algorithm for the organization of information by GM Adel'son-Vel ...
    An algorithm for the organization of information by G. M. Adel'son-Vel'skii and E. M. Landis. Soviet Mathematics Doklady, 3, 1259-1263, 1962.Missing: tree original
  40. [40]
    [PDF] Tree Rotations and AVL Trees
    Apr 6, 2015 · Named after its two Soviet inventors,. Georgy Adelson-Velsky and E. M. Landis, who described. AVL tres in a paper in 1962. First invention of ...
  41. [41]
    Adelson-Velsky and Landis trees (AVL) - University of Vermont
    Jan 5, 2025 · AVL trees are a kind of balanced binary search tree, invented in 1962 by Adelson-Velsky and Landis. Balancing avoids pathological structures and keeps ...Missing: paper | Show results with:paper
  42. [42]
    [PDF] Algorithms - cs.Princeton
    red−black tree. Page 22. Red-black BST representation. Each node is pointed to ... ・Internal nodes contain copies of keys to guide search. 48. B-trees (Bayer- ...
  43. [43]
    [PDF] Left-leaning Red-Black Trees - Robert Sedgewick
    In this paper, we describe a new variant of red- black trees that meets many of the original design goals and leads to substantially simpler code for insert/ ...
  44. [44]
    Self-adjusting binary search trees | Journal of the ACM
    The splay tree, a self-adjusting form of binary search tree, is developed and analyzed. The binary search tree is a data structure for representing tables ...Missing: original | Show results with:original
  45. [45]
    [PDF] Self-Adjusting Binary Search Trees
    Abstract. The splay tree, a self-adjusting form of binary search tree, is developed and analyzed. The binary search tree is a data structure for ...
  46. [46]
    Sequential access in splay trees takes linear time | Combinatorica
    Sleator and Tarjan have invented a form of self-adjusting binary search tree called thesplay tree. On any sufficiently long access sequence, splay trees are ...Missing: original | Show results with:original
  47. [47]
    Balanced Search Trees - Washington
    The amortized running time for one operation is O(log n). This guarantees that even if the depths of some nodes get very large, you can't get a big sequence ...
  48. [48]
    [PDF] Exercises on Catalan and Related Numbers
    Exercises on Catalan and Related Numbers excerpted from Enumerative Combinatorics, vol. 2. (published by Cambridge University Press 1999) by Richard P. Stanley.
  49. [49]
    Trees and jumps and real roots - ScienceDirect.com
    ... number of binary trees with n nodes. That number is known to be the nth Catalan number, that is, the right-hand side of the asserted equation [1]. □. Remark ...
  50. [50]
    [PDF] Catalan Numbers - Cornell Mathematics
    A full binary tree is a binary tree where each vertex has either zero or two children. Here are the five full binary trees on 7 vertices: Exercise 3.5. For each ...
  51. [51]
    [PDF] Combinatorial Mathematics Notes - People | MIT CSAIL
    ... binary trees with n 1 leaves is the nth Catalan number,. 1 n 1. 2n n . Example ... Catalan number over n factorial. Exercise 1.3.5. Probability that the ...
  52. [52]
    The Catalan Numbers - Discrete Mathematics - An Open Introduction
    We are looking at binary trees ... Stanley includes 66 different interpretations of the Catalan numbers in the book Enumerative Combinatorics: Volumne 2.
  53. [53]
    Eugène Catalan (1814 - 1894) - Biography - MacTutor
    In the same journal, he published two papers in 1838: Note sur un Problème de combinaisons Ⓣ. (Note on a problem of combinations). , and Note sur une Équation ...
  54. [54]
    [PDF] History of Catalan numbers - UCLA Mathematics
    Combining these two formulas with (5) easily implies (1). In 1838, French4 and Belgium mathematician Eug`ene Charles Catalan (1814–1894) was a répétiteur at ...
  55. [55]
    Binary Search Trees
    A binary search tree is a tree where each node has a left and right child. Either child, or both children, may be missing.Missing: CLRS | Show results with:CLRS
  56. [56]
    [PDF] DATA STRUCTURES - UMD Department of Computer Science
    The main drawback of linked allocation is the necessity of additional storage for the pointers. However, when implementing complex data structures (e.g., the ...
  57. [57]
    [PDF] Chapter 20 - Binary Trees
    Trees are often used to store large collections of data in a hierarchical manner where elements are arranged in successive levels. For example, file systems are ...
  58. [58]
    Binary Trees in C++
    Not every linked structure made up of tree nodes is a binary tree. A binary tree must have the following properties: There is exactly one node in the tree ...
  59. [59]
    [PDF] The Adaptive Radix Tree: ARTful Indexing for Main-Memory ...
    Rao and Ross [5] showed that T-trees, like all binary search trees, suffer from poor cache behavior and are therefore often slower than B+-trees on modern ...
  60. [60]
    Binary trees — ORIE 6125
    A binary tree is a tree structure where each node has at most two children. Some data is stored at each node. Nodes with children are called interior nodes.
  61. [61]
    Binary Trees
    A tree is a data structure which can be used to represent data which falls into a natural hierarchy. These notes primarily deal with binary trees.
  62. [62]
    Succinct Representation of Balanced Parentheses and Static Trees
    We consider the implementation of abstract data types for the static objects: binary tree, rooted ordered tree, and a balanced sequence of parentheses.
  63. [63]
    (PDF) Prüfer-like codes for labeled trees - ResearchGate
    Aug 4, 2025 · In this paper we survey and classify these Prüfer-like codes as well as new codes based on the parameter values of the proposed generic tree-encoding algorithm.Missing: succinct | Show results with:succinct
  64. [64]
    [PDF] Representing Graphs by Knuth Trees - Computer Science
    By means of the :Knuth transform, arbitrary rooted trees may be represented compactly ... The Art of Computer Programming, Vol. I: Fundamental Algorithms. Addison ...
  65. [65]
    27.9. General Tree Implementations - OpenDSA
    Each node contains a value, a pointer (or index) to its parent, and a pointer to a linked list of the node's children, stored in order from left to right. Each ...
  66. [66]
    Introduction to Algorithms - MIT Press
    A comprehensive update of the leading algorithms text, with new material on matchings in bipartite graphs, online algorithms, machine learning, and other ...
  67. [67]
    The Art of Computer Programming (TAOCP)
    This PDF includes the complete indexes of Volumes 1, 2, 3, 4A, and 4B, as well as the index to Volume 1 Fascicle 1. Registered owners of the earlier four-volume ...
  68. [68]
    Binary Tree Traversals
    Binary trees can be traversed in multiple ways. These notes describe four different traversals: preorder, inorder, postorder, and level order.
  69. [69]
    [PDF] CS 261: Data Structures Binary Tree Traversals Binary Search Trees
    Binary tree traversals examine nodes in a tree, with common orders being pre-order, in-order, and post-order. Binary search trees have nodes greater than left ...
  70. [70]
    Traversing Binary Trees
    Mar 11, 2025 · Many algorithms for manipulating trees need to “traverse” the tree, to visit each node in the tree and process the data in that node.
  71. [71]
    [PDF] Introduction to Algorithms and Data Structures What is a Binary Tree
    There are three common ways to traverse a tree: – Preorder: Visit the root, traverse the left subtree. (preorder) and then traverse the right subtree (preorder).
  72. [72]
    Operations on Binary Search Tree's
    There are several methods of traversing trees. Among them are the inorder, preorder and postorder traversal of nodes. Each of these traversal algorithms visit ...
  73. [73]
    7.5. Binary Tree Traversals — CS3 Data Structures & Algorithms
    5.3.​​ Instructions: Reproduce the behavior of binary tree inorder traversal. Click nodes to indicate the order in which the traversal algorithm would visit them.
  74. [74]
    Binary Trees
    Remember that, in addition to the breadth-first traversal algorithm, there are three ways to traverse a tree using depth-first traversal algorithms. Because ...
  75. [75]
    Traversing binary trees simply and cheaply - ScienceDirect
    View PDF; Download full issue. Search ScienceDirect. Elsevier · Information ... Traversing binary trees simply and cheaply. Author links open overlay panel
  76. [76]
    [PDF] Chapter 6 Binary Trees - Introduction to Web Development
    • A binary tree is a tree whose nodes have two children (possibly empty) ... Figure 6-21 Tree traversal with the Morris method (continued). Page 36. Data ...
  77. [77]
    Trie memory | Communications of the ACM
    R. DE LA BRIANDAIS. File searching using variable length keys. Proceedings, Western Joint Computer Conference, 1959, pp. 295-298. ... E. FREDKIN, Trie memory.Missing: original | Show results with:original
  78. [78]
    [PDF] parallel merge sort - CMU School of Computer Science
    First, rather than use a binary tree to guide the merges, we use an r-way tree. This tree has height h log n/log r. Second, we define the array SUP(v) to ...
  79. [79]
    Induction of decision trees | Machine Learning
    This paper summarizes an approach to synthesizing decision trees that has been used in a variety of systems, and it describes one such system, ID3, in detail.