class_docstr: Base class for Hoeffding Decision Trees.
  
  This is an **abstract class**, so it cannot be used directly. It defines base operations
  and properties that all the Hoeffding decision trees must inherit or implement according to
  their own design.
  
  Parameters
  ----------
  max_depth
      The maximum depth a tree can reach. If `None`, the tree will grow indefinitely.
  binary_split
      If True, only allow binary splits.
  max_size
      The max size of the tree, in Megabytes (MB).
  memory_estimate_period
      Interval (number of processed instances) between memory consumption checks.
  stop_mem_management
      If True, stop growing as soon as memory limit is hit.
  remove_poor_attrs
      If True, disable poor attributes to reduce memory usage.
  merit_preprune
      If True, enable merit-based tree pre-pruning.
code: def __init__(
      self,
      max_depth: int | None = None,
      binary_split: bool = False,
      max_size: float = 100.0,
      memory_estimate_period: int = 1000000,
      stop_mem_management: bool = False,
      remove_poor_attrs: bool = False,
      merit_preprune: bool = True,
  ):
      # Properties common to all the Hoeffding trees
      self._split_criterion: str = ""
      self._leaf_prediction: str = ""
  
      self.max_depth: float = (
          max_depth if max_depth is not None else math.inf
      )
      self.binary_split: bool = binary_split
      self._max_size: float = max_size
      self._max_byte_size: float = self._max_size * (
          2**20
      )  # convert to byte
      self.memory_estimate_period: int = memory_estimate_period
      self.stop_mem_management: bool = stop_mem_management
      self.remove_poor_attrs: bool = remove_poor_attrs
      self.merit_preprune: bool = merit_preprune
  
      self._root: DTBranch | HTLeaf = None  # type: ignore
      self._n_active_leaves: int = 0
      self._n_inactive_leaves: int = 0
      self._inactive_leaf_size_estimate: float = 0.0
      self._active_leaf_size_estimate: float = 0.0
      self._size_estimate_overhead_fraction: float = 1.0
      self._growth_allowed = True
      self._train_weight_seen_by_model: float = 0.0
  
imports: from __future__ import annotations
  import collections
  import functools
  import io
  import math
  from abc import ABC, abstractmethod
  from river import base
  from river.utils.norm import normalize_values_in_dict
  from .nodes.branch import DTBranch, NominalBinaryBranch, NominalMultiwayBranch, NumericBinaryBranch, NumericMultiwayBranch
  from .nodes.leaf import HTLeaf
  from .utils import calculate_object_size
label_desc: Use image node_id 1 to create a new HoeffdingTree object from inherited base classes: ABC with example: obj = HoeffdingTree(max_depth, binary_split, max_size, memory_estimate_period, stop_mem_management, remove_poor_attrs, merit_preprune)