Foundationপ্রথম নীতি থেকে
LEVEL 6লেসন ৭/২৪মাঝারি৪৫ মিনিট

Binary Tree — hierarchy-র সবচেয়ে সরল রূপ

Binary Trees and Traversals

Binary tree হলো hierarchy-র সবচেয়ে সরল রূপ — প্রতিটা node-এর হাতে মাত্র দুইটা pointer, আর traversal মানে সেই tree-এর প্রতিটা node-কে ঠিক একবার করে ঘুরে দেখা, চারটা ভিন্ন নিয়মে।

এই লেসন শেষে আপনি পারবেন

  • node, left child, right child দিয়ে binary tree-এর vocabulary ব্যবহার করে যেকোনো tree-এর depth, height, level হাতে হিসাব করতে পারবেন
  • full, complete, perfect, degenerate — চারটা shape চিনে বলতে পারবেন কোন shape-এ pointer chase সবচেয়ে খারাপ, কোনটায় array-তে বসানো যায়
  • একই tree-এর pre-order, in-order, post-order আর level-order traversal হাতে-কলমে লিখে দেখাতে পারবেন
  • recursion-এর call stack আর explicit stack-এর equivalence ব্যাখ্যা করে যেকোনো recursive traversal loop + stack দিয়ে লিখতে পারবেন
  • expression tree থেকে infix, postfix, prefix form বের করতে পারবেন এবং এটাকে compiler-এর AST-এর সাথে যুক্ত করতে পারবেন

আগে যা বোঝা থাকা দরকার

আগে এটা বুঝি

গত লেসনে stack, queue, deque — সব linear: প্রতি node-এ মাত্র একটা next pointer, একটা রাস্তা।

কিন্তু বাস্তবের বেশিরভাগ তথ্য শাখায় বিভক্ত: directory-র নিচে directory, tag-এর ভেতরে tag, manager-এর নিচে team — এমনকি 2 + 3 * 4 expression-ও ভেতরে ভেতরে শাখাওয়ালা。

এই hierarchy-র সবচেয়ে সরল, বহুল ব্যবহৃত ধারক tree — আজকের বিষয় তার প্রথম রূপ binary tree: প্রতি node-এ সর্বোচ্চ দুইটা pointer (left, right)। linked list-এর চেয়ে ঠিক একটা বেশি — অথচ এই একটা pointer সম্ভাবনার জগৎ বদলে দেয়।

আজকের প্রশ্ন দুইটা: (১) tree বর্ণনার ভাষা — depth, height, আকৃতি? (২) প্রতিটা node ঘোরার নিয়ম — কারণ tree-তে “প্রথম থেকে শেষ” বলে একটাই ক্রম নেই; নিয়ম ঠিক করলেই চার traversal জন্মায়।

মূল ধারণা

Node, left, right — পুরো vocabulary একটা ছবিতে

            A          ← root
          /   \
         B       C
        / \     / \
       D   E   F   G    ← এরা সবাই leaf
শব্দঅর্থ
nodevalue + left + right pointer
root / leafসবার উপরের node (parent নেই) / child-হীন node (D..G)
parent / childB হলো D-এর parent; D হলো B-র left child
subtreeকোনো node + তার descendants — নিজেই পূর্ণ tree

Python-এ একটা node মাত্র তিনটা field: value, left, right — দুই pointer শুরুতে None। (Build অংশে পূর্ণ class আছে।)

Height, depth, level — একই রকম শোনায়, এক না

  • Depth (of a node) — root থেকে সেই node পর্যন্ত edge সংখ্যা; root-এর depth = 0, উপরের ছবিতে D-এর depth = 2।
  • Height (of a node) — node থেকে সবচেয়ে দূরের descendant leaf পর্যন্ত edge; leaf-এর height = 0।
  • Height (of the tree) — root-এর height; উপরের ছবিতে = 2।
  • Level — একই depth-এর সব node; root বসে level 1-এ (level = depth + 1)।

চারটা আকৃতি — আর পারফরম্যান্স মানে

Full:      প্রতি node-এ 0 বা 2 child     Complete: শেষ level ছাড়া সব ভরা,
                                                   শেষটা বাঁ দিকে জমা
    o              o                        o            o
   / \            / \                      / \          / \
  o   o          o   o                    o   o        o   o
 / \                                         /              /
o   o                                       o              o

Perfect: সব leaf একই depth       Degenerate: সবার এক child — linked list!
    o                                 o
   / \                                 \
  o   o                                 o
                                           \
                                            o

নামের জন্য না — পারফরম্যান্সের জন্য: perfect-এর height log₂(n+1) − 1, degenerate-এর n − 1 — একই node, আকাশ-পাতাল গভীরতা। আর এক level নামা = এক pointer-hop = সম্ভাব্য cache trip; হিসাবটা Under the Hood-এ পাকা হবে。

আকৃতি (n node)Heightমন্তব্য
Perfectlog₂(n+1) − 1search-এর স্বপ্ন
Complete⌊log₂ n⌋Heap এখানেই বসে
Full… n−1 পর্যন্তনিয়ম আছে, balance নেই
Degeneraten − 1linked-list ছদ্মবেশ

ভেতরে কী ঘটছে

Traversal — কেন একটাই উত্তর নেই

প্রতিটা মোড়ে দুইটা রাস্তা — তাই প্রশ্ন: node-এর নিজের কাজ (print, compare, free) কখন হবে — বাঁয়ে যাওয়ার আগে, নাকি দুই পাশ ঘুরে ফিরে এসে?

চারটা traversal — node-এর "নিজের কাজ" কখন হয়
  1. Pre-ordernode আগে, তারপর বাঁয়া subtree, তারপর ডানা
  2. In-orderবাঁয়া, তারপর node, তারপর ডানা — node মাঝখানে (in)
  3. Post-orderবাঁয়া, ডানা, শেষে node — কাজ সবার পরে (post)
  4. Level-orderউপর থেকে নিচে, বাঁ থেকে ডানে — DFS নয়, BFS

Recursive কোডে তিনটা DFS traversal একটার ভাই — শুধু একটা লাইনের জায়গা বদলায়:

def inorder(node):                  # left → node → right
    if node is None:
        return
    inorder(node.left)
    visit(node)                     # pre-order-এ এই লাইন সবার আগে,
    inorder(node.right)             # post-order-এ সবার পরে — ব্যস!

# pre / in / post = root-এর কাজটা কখন হয়; বাঁ-আগে-ডান ক্রম সবগুলোতেই এক।

Call stack-ই তো একটা stack

উপরের কোডে আমরা stack লিখিনি — অথচ ব্যবহার হচ্ছেই। প্রতিটা pending call মানে recursion-এর call stack-এ একটা frame: কোন node-এ আছি, ফিরে কী করতে হবে। Recursion-এর সুবিধা — bookkeeping compiler করে দেয়; অসুবিধা — stack-টা আপনার হাতে নেই।

Degenerate tree-তে (height n−1) recursive inorder n frame খায় — Python-এর limit ~১০০০ ছাড়ালেই RecursionError, নিচের level-এ আসল stack overflow। সমাধান: explicit stack — নিজের list-এ কাজ-তালিকা, loop। Build-এ চারটাই recursion-ছাড়া লিখব।

Level-order? “যে node আগে পেলাম তার children-ও আগে” — FIFO: stacks-queues-deques লেসনের deque-ই হাতিয়ার। Stack দিলে শেষে-pushed child আগে বেরোয় — গভীরে চলে যাবেন, level-ক্রম নষ্ট। (queue-vs-stack- এর এই ফারাক graph-এ BFS vs DFS হয়ে ফিরবে。)

Memory-তে এই tree আসলে কেমন

Node-রা heap-এ আলাদা আলাদা allocate হয় — পাশাপাশি থাকার নিশ্চয়তা নেই। এক level নামা = এক dereference; cache-এর বাইরে গেলে পূর্ণ cache miss। এটাই locality of reference-এর শত্রু নং ১: pointer chasing। Perfect খোঁজার log₂ n hop দুর্দান্ত asymptotic, কিন্তু প্রতি hop সম্ভাব্য cache line fetch। Complete tree হলে pointer-ই লাগে না — পুরোটা array-তে; জাদুটা heaps-লেসনে।

Expression tree — operator ভেতরে, operand পাতায়

(2 + 3) * 4:

        *                pre-order:  * + 2 3 4   (prefix)
      /   \              in-order:   2 + 3 * 4   (infix — parens ছাড়া ambiguous!)
     +     4             post-order: 2 3 + 4 *   (postfix / RPN)
    / \
   2   3

Postfix-এ operator-এর দরকারের আগেই দুই operand হাতে — stack-machine ভালোবাসে। আর এই tree-টাই compiler-এর AST-এর নমুনা: parser source থেকে tree, optimizer সেখানে rewrite, code generator থেকে machine code — compilers module-এর ast-design প্রসঙ্গ এখান থেকেই শুরু।

উদাহরণ

একটা tree, চারটা traversal — হাতে করে

            A
          /   \
         B     C
        / \   / \
       D   E F   G

In-order ধাপে ধাপে (বাঁয়া পুরো, তারপর node, তারপর ডানা):

inorder(A)
 ├─ inorder(B) → D, B, E        (D leaf; B-এর কাজ মাঝে; E leaf)
 └─ A প্রিন্ট
 └─ inorder(C) → F, C, G
TraversalOutputচেনার দাগ
Pre-orderA B D E C F Gপ্রথম element-ই root
In-orderD B E A F C Groot মাঝে পড়ে
Post-orderD E B F G C Aশেষ element root
Level-orderA B C D E F Gউপর→নিচ, বাঁ→ডান

আর in-order output D B E A F C G — বর্ণানুক্রমে সাজানো! কৈফিয়ত না — letters “বাঁয়ে ছোট, ডানে বড়” মেনে বসানো। সেই নিয়মই BST — পরের লেসনের hero; এই পর্যবেক্ষণই সেখানকার স্ট্রাকচারের ভিত্তি।

ছবিতে

একই tree-এর তিনটা চেহারা

depth:      0        1        2        (level: 1, 2, 3)

                      A
                   /     \
                 B         C        ← A-র height = 2
               /   \     /   \
              D     E   F     G     ← leaf-দের height = 0

tree height = 2;  nodes = 7 = 2³−1;  edges = 6 = nodes−1

nested text: (A (B (D) (E)) (C (F) (G)))
পড়ার নিয়ম: প্রতি বন্ধনী-জোড়া = node; ভেতরে বাঁ subtree, ডান subtree।
JSON, Lisp source, বহু config format এই ভাষাতেই কথা বলে।

traversal strips:
pre:   A B D E C F G        in:   D B E A F C G        post: D E B F G C A
Depth, height, level — আর nested-parenthesis serialization, একসাথে।

নিজে চালিয়ে দেখুন

EXPERIMENT

Tree বানান, ঘোরান, আর Catalan-এর গোয়েন্দা হোন

Python 3.8+· ১০ মিনিট
from collections import deque

class Node:
    __slots__ = ('value', 'left', 'right')
    def __init__(self, value):
        self.value, self.left, self.right = value, None, None

def build_sample():
    d, e, f, g = Node('D'), Node('E'), Node('F'), Node('G')
    b, c = Node('B'), Node('C')
    b.left, b.right, c.left, c.right = d, e, f, g
    a = Node('A'); a.left, a.right = b, c
    return a

def preorder(n):  return [] if not n else [n.value] + preorder(n.left) + preorder(n.right)
def inorder(n):   return [] if not n else inorder(n.left) + [n.value] + inorder(n.right)
def postorder(n): return [] if not n else postorder(n.left) + postorder(n.right) + [n.value]

def levelorder(n):
    out, q = [], deque([n] if n else [])
    while q:
        x = q.popleft()
        out.append(x.value)
        if x.left:  q.append(x.left)
        if x.right: q.append(x.right)
    return out

def nested_text(n):
    if not n: return ''
    if not n.left and not n.right: return f'{n.value}'
    return f'({n.value} {nested_text(n.left)} {nested_text(n.right)})'

t = build_sample()
for name, fn in (('pre', preorder), ('in', inorder),
                 ('post', postorder), ('lvl', levelorder)):
    print(f'{name:4s}:', ' '.join(fn(t)))
print('nested:', nested_text(t))

# --- Catalan teaser: n node-এ কত ভিন্ন আকৃতি? ---
from functools import lru_cache
import math

@lru_cache(maxsize=None)
def shapes(n):
    """n node-এর structurally distinct binary tree"""
    if n \<= 1: return 1
    return sum(shapes(l) * shapes(n - 1 - l) for l in range(n))

for n in range(1, 11):
    assert shapes(n) == math.comb(2 * n, n) // (n + 1)   # closed form
print('Catalan:', [shapes(i) for i in range(1, 11)])

প্রত্যাশিত output:

pre : A B D E C F G
in  : D B E A F C G
post: D E B F G C A
lvl : A B C D E F G
nested: (A (B D E) (C F G))
Catalan: [1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796]

যাচাই করুন: চার output টেবিলের সাথে মিলছে? আর Catalan সংখ্যা — মাত্র ১০ node-এ ১৬,৭৯৬ আকৃতি। একই value ভিন্ন ক্রমে ঢুকলেই ভিন্ন আকৃতি, ভিন্ন height, ভিন্ন গতি — পরের লেসনের নাটকের seed।

এটা কী প্রমাণ করে

একই tree চার traversal-এ চার ক্রম দেয়; n node দিয়ে বানানো যায় এমন ভিন্ন আকৃতির সংখ্যা Catalan(n) — exponential ভাবে ফুঁসে ওঠে, তাই 'আকৃতি কেমন হবে' ঠিক করাটাই performance-এর আসল লেগো।

নিজে বানান

BUILD IT

BinaryTree class — চারটা traversal, কোনো recursion ছাড়া

Python · ●●○○○
  1. insert_level_order দিয়ে list থেকে complete-ish tree (queue ব্যবহার)
  2. pre/in-order iterative — একটা stack
  3. post-order iterative — two-stack trick
  4. level-order — queue (BFS)
  5. draw(): ঘুরানো ASCII pretty-printer + recursive ফলাফলের সাথে assert

মূল চ্যালেঞ্জ recursion-ছাড়া post-order: two-stack trick — modified pre-order (node→right→left) চালিয়ে ফল উল্টে দিন।

from collections import deque

class Node:
    __slots__ = ('value', 'left', 'right')

    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

class BinaryTree:
    def __init__(self):
        self.root = None

    def insert_level_order(self, values):
        if not values:
            return
        self.root = Node(values[0])
        q, i = deque([self.root]), 1
        while q and i \< len(values):
            node = q.popleft()
            if i \< len(values):
                node.left = Node(values[i]); i += 1
                q.append(node.left)
            if i \< len(values):
                node.right = Node(values[i]); i += 1
                q.append(node.right)

    def preorder(self):
        out, stack = [], [self.root] if self.root else []
        while stack:
            n = stack.pop()
            out.append(n.value)
            if n.right: stack.append(n.right)   # ডান আগে push —
            if n.left:  stack.append(n.left)    # তাই বাঁ আগে pop
        return out

    def inorder(self):
        out, stack, cur = [], [], self.root
        while cur or stack:
            while cur:                  # বাঁয়ের দেয়াল ধরে নামো
                stack.append(cur)
                cur = cur.left
            cur = stack.pop()
            out.append(cur.value)       # node-এর কাজ
            cur = cur.right             # এবার ডান subtree
        return out

    def postorder(self):
        if not self.root:
            return []
        s1, s2 = [self.root], []
        while s1:
            n = s1.pop()
            s2.append(n)
            if n.left:  s1.append(n.left)
            if n.right: s1.append(n.right)
        return [n.value for n in reversed(s2)]

    def levelorder(self):
        out, q = [], deque([self.root] if self.root else [])
        while q:
            n = q.popleft()
            out.append(n.value)
            if n.left:  q.append(n.left)
            if n.right: q.append(n.right)
        return out

    def draw(self):
        lines = []
        def rec(n, depth):               # শুধু printer-এ recursion মাফ
            if not n: return
            rec(n.right, depth + 1)
            lines.append('    ' * depth + str(n.value))
            rec(n.left, depth + 1)
        rec(self.root, 0)
        return '\n'.join(lines)

if __name__ == '__main__':
    t = BinaryTree()
    t.insert_level_order(['A', 'B', 'C', 'D', 'E', 'F', 'G'])
    print(t.draw(), end='\n\n')

    # recursion-এর সাথে মিলিয়ে দেখা — দুই পথ, এক উত্তর
    assert t.preorder()  == ['A', 'B', 'D', 'E', 'C', 'F', 'G']
    assert t.inorder()   == ['D', 'B', 'E', 'A', 'F', 'C', 'G']
    assert t.postorder() == ['D', 'E', 'B', 'F', 'G', 'C', 'A']
    print('pre :', t.preorder())
    print('in  :', t.inorder())
    print('post:', t.postorder())
    print('lvl :', t.levelorder())
    print('সব assert পাস — iterative == recursive ✓')

প্রত্যাশিত output:

        G
    C
        F
A
        E
    B
        D

pre : ['A', 'B', 'D', 'E', 'C', 'F', 'G']
in  : ['D', 'B', 'E', 'A', 'F', 'C', 'G']
post: ['D', 'E', 'B', 'F', 'G', 'C', 'A']
lvl : ['A', 'B', 'C', 'D', 'E', 'F', 'G']
সব assert পাস — iterative == recursive ✓

(ছবিটা ৯০° ঘুরানো — head বাঁয়ে হেলান দিলেই চেনা tree।)

নিজে বাড়ান: size()/height() iterative; nested-text serialize/ deserialize; ৫০০০-node chain-এ recursive inorder-এর RecursionError vs আপনার iterative ভার্সন।

বাস্তব সিস্টেমে

যেখানে যেখানে binary tree লুকিয়ে আছে

  • DOM ও render engines: webpage-এর গঠন tree; CSS matching, event bubbling, প্রতি frame-এ reconciliation — সব tree-walk।
  • Compiler-এর AST: parser expression tree বানায়, optimizer post-order-এ ভেতর-থেকে-বাইরে rewrite করে — child প্রসেস না হলে parent-এর কাজ শুরুই হয় না; post-order-এর প্রাণবন্ত ব্যবহার।
  • Serialization + Huffman coding: pre-order + null marker-এ tree wire-এ; Huffman-এ character = root-to-leaf path — ZIP/JPEG-এর ভেতরে।
  • Graphics: ray tracing-এ bounding-volume hierarchy — GPU প্রতি pixel-এ BVH-descent।

দুইটা প্রশ্ন সবখানে: কোন ক্রমে ঘুরব, আর কতটা চ্যাপ্টা — প্রথমটা আজ, দ্বিতীয়টা পরের দুই লেসন।

যে ভুলগুলো সবাই করে

“Height আর depth একই জিনিসের দুই নাম।”

Depth: root থেকে node-এ — root-এর depth সবসময় 0। Height: node থেকে গভীরতম leaf — leaf-এর height 0; root-এর height-ই tree-র height। Perfect tree-তে depth + subtree-height = tree height — যাচাই করলে আর গুলাবেন না。

“In-order traversal সবসময় sorted output দেয়।”

Sorting in-order-র সংজ্ঞায় নেই — A-র বাঁয়ে Z বসালেই output Z A ...। Sorted হয় শুধু BST invariant (“বাঁয়ে ছোট, ডানে বড়”) থাকলে; invariant ছাড়া in-order এলোমেলো ক্রম মাত্র।

“Level-order-ও DFS-এরই রকম — stack বদলে queue বসালেই হয়ে যায়।”

Level-order depth-first family-র সদস্যই না — এটা BFS, ভিন্ন ভ্রমণ-দর্শন। Queue-ই natural ইঞ্জিন (FIFO-ই level-ধারাবাহিকতা); stack দিয়ে করতে গেলে per-level batching-এর জটিলতা। Tree→graph-এ গেলে এই পার্থক্য আরো জরুরি — shortest path BFS-এর জন্মসিদ্ধি, DFS ভুল দেয়।

“'Complete' আর 'full'-এ ব্যাপার একই।”

Full = প্রতি node-এ 0 বা ২ child; Complete = উপরের levels ভরা + শেষ level বাঁ থেকে ভরা (position-নিয়ম); Perfect = দুটোই + সব leaf এক depth-এ। Complete-এর বিশেষ দাম: একমাত্র এই আকৃতিতেই tree array-index arithmetic-এ encode হয় — pointer-খরচ শূন্য。

বুঝেছেন কি না দেখুন

1

Tree-টার জন্য লিখুন: (ক) প্রতিটা node-এর depth, (খ) tree height, (গ) চার traversal-এর output।

        1
       / \
      2   3
       \    \
        4    5
স্মরণ

(ক) depth: 1→0; 2,3→1; 4,5→2। (খ) height = 2।

(গ) pre: 1 2 4 3 5; in: 2 4 1 3 5 (2-র left নেই, তাই 2 আগে); post: 4 2 5 3 1; level: 1 2 3 4 5।

(Tree-টা full না, complete-ও না — 4 বসেছে 2-এর ডানে — degenerate-ও না। বাস্তবের tree কোনো পরিচ্ছন্ন বিভাগে পড়েই না।)

2

Pre-order A B D C, in-order B D A C — tree পুনর্গঠন করুন। শুধু pre+post দিলে কি সবসময় সম্ভব?

যুক্তি

Root = pre-এর প্রথম A; in-order-তে বাঁয়ে B D, ডানে C। বাঁ subtree-র pre B D, in B D: root B, বাঁয়ে কিছু নেই → D হলো B-র ডান child। ডান subtree: node C একা। ফল: A-র বাঁয়ে B (ডানে D), ডানে C।

Pre+post দিয়ে না — single-child chain-এ child বাঁয়ে নাকি ডানে, দুই তালিকাই ধরতে পারে না। Ambiguity কাটে in-order জড়ালে — সেটাই বাঁ-ডান সীমানা স্পষ্ট করে।

3

Tree-এর সব node free() করতে চান। কোন traversal, কেন? ভুলটা করলে ঠিক কী বিপদ?

প্রয়োগ

Post-order: free-র আগে child-রা — তাদের address parent-এর pointer-এ! Pre/in-order-তে parent মাঝপথে free হলে use-after-free + leak। Compiler shutdown-path-এ ঠিক এই সিদ্ধান্তই থাকে。

4

Perfect tree-র height h (edge convention) হলে মোট node ও leaf কত? h=10 হিসাব করুন। উল্টো: ১০ লাখ node-এর perfect tree-র height?

যুক্তি

Level i-তে 2^i node; মোট 2^(h+1) − 1, leaf 2^h। h=10: মোট 2047, leaf 1024। উল্টোদিকে 2^(h+1) − 1 = 10⁶ → h ≈ 19।

বিস্ময়টাই tree-র অর্থনীতি: ২০ level-এ ১০ লাখ node — linear scan-এর ১০ লাখ touch-এর বিপরীতে ~২০ pointer-touch। (প্রতি hop cache hit না — সেই হিসাব পরের লেসনগুলোর খাবার।)

5

Expression tree-র post-order output 8 2 ^ 3 + (^ = power)। Infix কী? In-order দিয়ে পুনর্গঠন কেন বিপজ্জনক?

ডিজাইন

Stack দিয়ে: 8,2 push; ^ → 8^2 push; 3 push; + → (8^2)+3। Infix: (8 ^ 2) + 3 = 67। In-order দিত 8 ^ 2 + 3 — এখানে ঠিক (precedence মিলেছে), কিন্তু (8−2)*3 tree-তে দিত 8 − 2 * 3 — মান ২, সঠিক ১৮। Grouping তথ্য হারায় বলে IR-এ postfix (RPN) প্রিয় — parenthesis-ই লাগে না।

এরপর কী

এরপর কী

আজ tree-র ভাষা: node, height, depth, চার আকৃতি, চার traversal, Catalan-এর exponential তালিকা। পরের লেসনে “বাঁয়ে ছোট, ডানে বড়” বসলে tree → Binary Search Tree — খোঁজা, ঢোকানো, মোছা log₂ n-এ। তারপর মোচড়: sorted input-এ degenerate হয়ে linked list — security attack পর্যন্ত। ঠেকাতে rotation, তার ওপর AVL ও red-black-এর রাজ্য। আজকের build-এর iterative traversal-গুলোই সেখানে validator হবে — ফেলে দেবেন না।

আরও পড়ুন

  • Introduction to Algorithms, 3rd ed., Section 12.1 — What is a binary search tree? — Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein · Binary tree-এর formal definition আর traversal-এর theorem — এই লেসনের in-order অংশের ভিত্তি
  • Algorithms, 4th ed., Section 3.2 — Binary Search Trees — Robert Sedgewick, Kevin Wayne · Traversal implementation-এর ব্যবহারিক রীতি আর iterator ডিজাইন
  • The Art of Computer Programming, Vol. 1, Section 2.3 — Trees — Donald E. Knuth · Tree-এর vocabulary, binary ও general tree-র সম্পর্ক, আর Catalan number-এর ক্লাসিক আলোচনা