Understanding Trees in Python
تعتبر الأشجار واحدة من هياكل البيانات الهامة في البرمجة، حيث توفر وسيلة لتنظيم البيانات بشكل هرمي. في بايثون، لا يوجد نوع بيانات مدمج للأشجار كما هو الحال مع القوائم أو المجموعات، ولكن يمكننا استخدام الكائنات والفئات لتعريف الأشجار وإنشاء بنيات مخصصة. الأشجار تتكون من عقد، حيث تحتوي كل عقدة على قيمة بالإضافة إلى مؤشرات للعقد الأخرى التي تعتبر أبناء لها. الشجرة الثنائية هي النوع الأكثر شيوعًا، حيث يمكن لكل عقدة أن تحتوي على اثنين من الأبناء كحد أقصى.
Implementing Trees in Python
لإنشاء شجرة في بايثون، يمكننا البدء بتعريف فئة للعقدة. تحتوي هذه الفئة عادة على خصائص لتخزين القيمة والمؤشرات للأبناء. يمكننا أيضًا إضافة أساليب لعمليات مثل الإضافة والحذف والبحث. على سبيل المثال، يمكننا تعريف فئة لعقدة الشجرة الثنائية كما يلي:
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class BinaryTree:
def __init__(self):
self.root = None
def insert(self, value):
if not self.root:
self.root = TreeNode(value)
else:
self._insert_recursively(self.root, value)
def _insert_recursively(self, node, value):
if value < node.value:
if not node.left:
node.left = TreeNode(value)
else:
self._insert_recursively(node.left, value)
else:
if not node.right:
node.right = TreeNode(value)
else:
self._insert_recursively(node.right, value)
في هذا المثال، لدينا فئة TreeNode لتخزين قيمة العقدة والمؤشرات لأبناءها. وفئة BinaryTree توفر طرق لإدخال قيمة جديدة في الشجرة بشكل متكرر.
Traversal Techniques
تعتبر عملية المرور عبر الشجرة جزءًا مهمًا من التعامل مع الأشجار. هناك عدة طرق للمرور عبر الأشجار، منها: المرور بالعمق أولاً (Depth-First Traversal) والمرور بالعرض أولاً (Breadth-First Traversal). في العمق أولاً، نزور كل عقدة في فرع قبل الانتقال إلى الفرع التالي. بينما في العرض أولاً، نزور كل عقدة في مستوى قبل الانتقال إلى المستوى التالي. لنلق نظرة على مثال للمرور بالعمق أولاً:
def in_order_traversal(node):
if node:
in_order_traversal(node.left)
print(node.value)
in_order_traversal(node.right)
# Example usage
tree = BinaryTree()
tree.insert(10)
tree.insert(5)
tree.insert(15)
in_order_traversal(tree.root)
في هذا المثال، نقوم بزيارة العقدة اليسرى أولاً، ثم العقدة الحالية، وأخيرًا العقدة اليمنى. بهذه الطريقة، نحصل على ترتيب تصاعدي للقيم.
