Trie (شجرة المقاطع) للمبتدئ: ازاي محرّك البحث بيكمّل كلمتك في 0.4 مللي ثانية
المستوى: مبتدئ — وقت القراءة: حوالي 9 دقايق
لو بتكتب "prog" في صندوق بحث جوجل وفي 0.4 مللي ثانية بتظهرلك 10 اقتراحات بدأ كلهم بـ "prog"، ده مش لأن جوجل بيدوّر في كل كلمة في الإنترنت. ده لأنه مستخدم هيكل بيانات اسمه Trie. في 9 دقايق هتفهم Trie من الصفر، تبنيه بإيدك في Python، وتقيس بنفسك ازاي بيلاقي الكلمة أسرع بـ 190 مرة من البحث العادي.
المشكلة باختصار
تخيّل عندك قائمة فيها 100 ألف كلمة إنجليزية، والمستخدم بيكتب حرف ورا حرف في صندوق البحث. كل ما بيكتب حرف، انت محتاج تعرض كل الكلمات اللي بتبدأ بالحروف اللي كتبها. لو عملت كده بـ for loop بسيط على الـ list، هتمرّ على 100 ألف كلمة في كل ضغطة زرار. ده ممكن ياخد 80 مللي ثانية. المستخدم هيحس إن الـ search box "بطيء" أو "بيلكز". وده اللي بيخلّي الـ UX مش طبيعي.
مثال من الحياة قبل أي كود
ركّز معايا في مثال بسيط جدًا. تخيّل قاموس ضخم في مكتبتك، فيه كل الكلمات الإنجليزية. لو حد سألك "هاتلي كل الكلمات اللي بتبدأ بـ ca"، انت مش هتفتح القاموس من الصفحة الأولى وتقرأ كل صفحة لحد ما تلاقي. انت هتفتح القاموس على حرف C، وبعدين هتلاقي قسم Ca، وتقرأ كل اللي تحته. ده بالظبط فكرة Trie. هيكل بيانات بيخزّن الكلمات بشكل بيخلّي البحث بحرف، وبعدين بحرف تاني، وبعدين بحرف تالت، شغال زي ما انت بتفتح القاموس بالظبط.
الفرق إن القاموس الورقي بيخزّن كل كلمة كاملة في صفحتها. أما Trie فا بيشارك الحروف المشتركة بين الكلمات. كلمات زي "car"، "card"، "care" كلها بتشارك أول 3 حروف (c، a، r) في عقد مشتركة، وبعدين بتفترق.
التعريف العلمي لـ Trie
Trie (واسمها كمان Prefix Tree) هي شجرة (tree data structure) كل عقدة (node) فيها بتمثل حرف واحد. الجذر (root) فاضي. كل مسار من الجذر لعقدة معيّنة بيمثّل بادئة (prefix) لكلمة أو لكلمات. بعض العقد بتتعلّم بـ flag اسمه end_of_word علشان نعرف إن المسار من الجذر لحد العقدة دي بيمثّل كلمة كاملة.
الاسم "Trie" جاي من كلمة "retrieval" لأنها اتصمّمت سنة 1960 بواسطة Edward Fredkin علشان تكون أداة سريعة لاسترجاع المعلومات النصية. بتنطق بطريقتين: "تراي" أو "تري"، الاتنين صح.
الفرضيات اللي مبني عليها الشرح
- Python 3.12 على لابتوب عادي (M1 / i7) مع 16GB RAM.
- قاموس إنجليزي حجمه 100 ألف كلمة (مصدره
nltk.corpus.words). - متوسط طول الكلمة 8 أحرف.
- قياس الأداء بـ
timeitعلى 1000 query. - الكود ده ما بيشتغلش بالكفاءة دي على لغات بأبجدية ضخمة زي الصينية. ده اعتباره منفصل تحت في "متى لا تستخدم".
ازاي نبني Trie في Python (الكود الكامل)
الكود ده شغال فعلًا. انسخه وجرّبه. هتلاقي إنه أبسط مما تتخيّل.