Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

شجرة البادئات (Trie)

آخر تحديث

شجرة البادئات (تُلفظ «تراي»)، أو trie، تخزّن مجموعة من السلاسل النصية حسب حروفها: كل حافة موسومة بحرف، والمسار من الجذر يهجئ بادئة. الكلمات التي تشترك في بادئة تشترك في العُقد نفسها، لذا فإن «car» و«card» و«care» تعيد جميعها استخدام المسار c-a-r. اضغط على تشغيل في الأعلى لمشاهدة الكلمات وهي تُدرَج حرفًا واحدًا في كل مرة، متفرّعةً فقط حيث تختلف.

بما أن عمليات البحث تمرّ بعُقدة واحدة لكل حرف، فإن البحث عن كلمة طولها m يستغرق O(m) بغضّ النظر عن عدد الكلمات التي تحتويها الشجرة. هذا يجعل أشجار البادئات مثالية للإكمال التلقائي والتدقيق الإملائي والبحث بالبادئة.

تعقيد الزمن والمساحة

العمليةالتعقيدملاحظات
الإدراجO(m)m = طول الكلمة
البحثO(m)خطوة واحدة لكل حرف
استعلام البادئةO(m)الوصول حتى عقدة البادئة
المساحةO(total chars)تُخزَّن البادئات المشتركة مرة واحدة

خطوة بخطوة (الإدراج)

الخطوةماذا يحدث
1ابدأ من العقدة الجذرية.
2لكل حرف في الكلمة، ابحث عن حافة ابن مطابقة.
3إن وُجدت، اتبعها (بإعادة استخدام البادئة المشتركة).
4إن لم تُوجد، أنشئ عقدة ابن جديدة لذلك الحرف.
5بعد الحرف الأخير، ضَع علامة على تلك العقدة كنهاية كلمة.

مثال محلول

إدراج ["car", "card", "care"] في شجرة بادئات فارغة:

الخطوةالبنيةالإجراء
إدراج carroot → c → a → r✓لا وجود لأبناء مطابقين، لذا أنشئ c وa وr وضع علامة على r كنهاية كلمة.
إدراج cardroot → c → a → r✓ → d✓أعد استخدام المسار الموجود c-a-r، ثم أنشئ ابنًا جديدًا d وضع عليه علامة نهاية كلمة.
إدراج careroot → c → a → r✓ → {d✓, e✓}أعد استخدام c-a-r، وتفرّع من r بابن جديد e، وضع علامة على e كنهاية كلمة.
البحث عن careroot → c → a → r → e✓امشِ عبر c وa وr وe؛ العقدة الأخيرة موسومة كنهاية كلمة، لذا فإن care موجودة.
البحث عن caroot → c → aالمسار موجود لكن a ليست موسومة كنهاية كلمة، لذا فإن ca بادئة وليست كلمة مخزّنة.

متى تستخدم شجرة البادئات

استخدمها عندماتجنّبها عندما
تحتاج إلى استعلامات بادئة أو إكمال تلقائي على مجموعة من السلاسل النصية.تحتاج فقط إلى البحث عن مفاتيح كاملة - جدول التجزئة أسرع وأخف.
تشترك كلمات مخزّنة كثيرة في بادئات مشتركة، فتُعاد استخدام العُقد.المفاتيح طويلة ونادرًا ما تتداخل، فتُهدَر عقدة لكل حرف.
تريد إرجاع المفاتيح بترتيب مرتّب عبر التنقّل.الذاكرة محدودة - مؤشرات الأبناء لكل عقدة تضيف عبئًا كبيرًا.
يجب أن تعتمد كلفة البحث على طول المفتاح لا على حجم مجموعة البيانات.الأبجدية ضخمة (مثل يونيكود بالكامل) وتُخزَّن الأبناء بكثافة.

كود Trie (Prefix Tree)

تنفيذ نظيف وقابل للتشغيل لخوارزمية Trie (Prefix Tree) بلغات Python, JavaScript, Java, C++, C. اختر لغة، وانسخ الكود، أو افتحه محمّلًا مسبقًا في ساحة تجربة Coddy.

كود Trie (Prefix Tree) بلغة Python

Python
1class TrieNode:2    def __init__(self):3        self.children = {}4        self.is_word = False5
6
7class Trie:8    def __init__(self):9        self.root = TrieNode()10
11    def insert(self, word):12        node = self.root13        for ch in word:14            node = node.children.setdefault(ch, TrieNode())15        node.is_word = True16
17    def search(self, word):18        node = self._walk(word)19        return node is not None and node.is_word20
21    def starts_with(self, prefix):22        return self._walk(prefix) is not None23
24    def _walk(self, s):25        node = self.root26        for ch in s:27            if ch not in node.children:28                return None29            node = node.children[ch]30        return node31
32
33trie = Trie()34for word in ["car", "card", "care", "dog"]:35    trie.insert(word)36
37print("search(card):     ", trie.search("card"))38print("search(ca):       ", trie.search("ca"))39print("starts_with(ca):  ", trie.starts_with("ca"))40print("starts_with(do):  ", trie.starts_with("do"))41print("starts_with(cat): ", trie.starts_with("cat"))
شغّل هذا الكود في ساحة تجربة Python

الأسئلة الشائعة حول شجرة البادئات

فيمَ تُستخدَم شجرة البادئات؟
تشغّل أشجار البادئات ميزات قائمة على البادئات: الإكمال التلقائي واقتراحات البحث، ومدقّقات الإملاء، وجداول توجيه IP، وعمليات البحث في القواميس. في أي مكان تحتاج فيه إلى إجابة سريعة عن «هل تبدأ أي كلمة مخزّنة بهذه البادئة؟»، تتألق شجرة البادئات.
ما هو التعقيد الزمني لشجرة البادئات؟
يعمل الإدراج والبحث واستعلامات البادئة جميعها في O(m)، حيث m هو طول الكلمة أو البادئة - بغضّ النظر عن عدد الكلمات المخزّنة. المفاضلة هي الذاكرة: قد تستهلك شجرة البادئات مساحة كبيرة، رغم أن البادئات المشتركة تُخزَّن مرة واحدة فقط.
ما الفرق بين شجرة البادئات وجدول التجزئة؟
يقدّم جدول التجزئة بحثًا متوسطًا في O(1) عن المفاتيح الكاملة لكنه لا يستطيع الإجابة عن استعلامات البادئة. شجرة البادئات أبطأ قليلًا لكل بحث لكنها تدعم بطبيعتها البحث بالبادئة والتنقّل المرتّب والإكمال التلقائي - وهو سبب تفضيلها في هذه الحالات.
متى ينبغي أن أستخدم شجرة البادئات بدلًا من شجرة بحث ثنائية؟
استخدم شجرة البادئات عندما تكون مفاتيحك سلاسل نصية وتحتاج إلى بحث بالبادئة: تعمل في O(m) لكل عملية على طول المفتاح، بينما تكلّف شجرة البحث الثنائية المتوازنة O(m log n) لأن كل مقارنة تمسح السلسلة وهناك log n منها. تكون شجرة البحث الثنائية الخيار الأفضل عندما لا تكون المفاتيح شبيهة بالسلاسل أو عندما يكون عبء الذاكرة أهم من سرعة البادئات.
كيف تُعالَج نهاية الكلمة في شجرة البادئات؟
تحمل كل عقدة علامة نهاية كلمة تُضبَط فقط عندما تنتهي عندها كلمة كاملة مُدرَجة. من دونها لن تستطيع التمييز بين كلمة مخزّنة ومجرّد بادئة - فمثلًا بعد إدراج card، توجد عقدة car لكن ينبغي الإبلاغ عنها ككلمة فقط إذا كانت car قد أُدرِجت أيضًا.
هل توفّر أشجار البادئات الذاكرة دائمًا من خلال مشاركة البادئات؟
ليس دائمًا. المشاركة تساعد فقط عندما تتداخل مفاتيح كثيرة؛ ومع مفاتيح طويلة ومختلفة قد تستهلك شجرة البادئات ذاكرة أكثر بكثير من مجموعة تجزئة، لأن كل حرف يصبح عقدته الخاصة بمؤشرات أبناء. إن كانت المساحة هي الهاجس، فإن شجرة الجذر المضغوطة (radix tree) تدمج سلاسل الابن الواحد لتقليص هذا العبء.
Coddy programming languages illustration

أتقن الخوارزميات مع Coddy

ابدأ الآن