الشجرة الرقمية (Trie)
Mohanad Alrwaihy
March 29, 2023
129
3
بعبارات بسيطة Trie هيا هيكلة بيانات تعتمد في عملها على (اجزاء من السلاسل Prefix of string) ويتم استخدامها لتخزين المفاتيح واسترجاعها بكفاءة في مجموعة بيانات من السلاسل (Strings).
4 دقائق للقراءة
ما هيا الشجرة الرقمية (Trie Data structure) ؟
بعبارات بسيطة Trie هيا هيكلة بيانات تعتمد في عملها على (اجزاء من السلاسل Prefix of string) ويتم استخدامها لتخزين المفاتيح واسترجاعها بكفاءة في مجموعة بيانات من السلاسل (Strings).
التطبيقات 🚀
- المكمل التلقائي
- كلمات البحث
- المدقق الإملائي
- تاريخ المتصفح
الميزات ⚡
الشجرة الرقمية Trie مميزة لأنها سريعة جدًا. فمثلا عند البحث عن كلمة تبدأ بـ A ، ستقوم بإزالة جميع الكلمات التي لا تبدأ بـ A وإذا كنت تبحث عن كلمة App ستقوم بتقليل الوقت الذي يستغرقه العثور على الكلمة بشكل هائل بدلاً من استخدام Array لحفظ قائمة الكلمات.
مثال تجريبي
تتكون Trie العادية من:
Root- هذه نقطة البداية في الشجرةTrie Node- يتم تمثيل كل حرف باستخدام عقدة لها خاصيتانChild- ستحتوي على قيمة العقدة نفسها والوصل بين العقد التابعة لهاIsEnd- عبارة عن True او False للعقدة الحالية ويعبر هل هذه العقدة تعبر عن نهاية كلمة معينة ام لا.
فيما يلي مثال على Trie تتكون من أربع كلمات (And, All, Bank, Bat) ويظهر هيكل Trie وكيف يمكننا البحث في الشجرة ومعرفة أين هي الكلمات:
مشاكل LeetCode 🔨
لتنفيذ بنية البيانات Trie ، سأستخدم مشكلتين من LeetCode لإظهار كيف يمكننا تنفيذ Trie واستخدامها لحل مشكلة حقيقية.
المشكلة 1: تنفيذ Trie (شجرة البادئة)
تحقق من تفاصيل المشكلة هنا.
متطلبات السؤال:
تنفيذ Trie Class:
Trie()- تهيئة كائن ل Trievoid insert(String word)- ادرج الكلمة المدخلة الى الTrieboolean search(String word)- نقوم بأرجاعtrueاذا كانت الكلمة موجودة في الTrieوfalseاذا لاboolean startsWith(String prefix)- إرجاعtrueإذا كان هناك سلسلةwordمدرجة مسبقا تحتوي على الprefixprefixوfalseاذا لم توجد.
خطوات 🪜 الحلول
الخطوة 1: تهيئة TrieNode
لإنشاء Trie أولا ، سنقوم بإنشاء كلاس باسم TrieNode الذي هو تمثيل لعقدة كل حرف و تحمل العقدة ال Value, Children, isEnd:
TYPESCRIPTclass TrieNode {
constructor(child = {}, isEnd = false) {
this.child = child
this.isEnd = isEnd
}
}بشكل افتراضي ، سيبدأ TrieNode بدون أي children و isEnd سيكون false حتى نقوم بإدراج حروف الكلمات وجعل عقدة الحرف الأخير من الكلمة في ال TrieNode لتكون True.
تصور لشكل الTrieNode أو الشجرة الرقمية :
الخطوة 2: تهيئة شجرة Trie (سلسلة الشجرة):
سيتم بدء كلاس Trie بقائمة تم تعيينها على TrieNode جديدة تمثل الجذر (نقطة البداية).
TYPESCRIPTclass Trie {
constructor() {
this.list = new TrieNode()
}
}تبدء الشجرة الرقمية بالجذر بهذا الشكل:
الخطوة 3: إضافة وظائف Trie:
لدينا ثلاث وظائف نريد إضافتها في كلاس Trie:
TYPESCRIPT// Insert new word to the list
insert(word: string): void {}
// Search for a word in the list
search(word: string): boolean {}
// Search if there is a word that start with specific set of characters.
startsWith(prefix: string): boolean {}
دعنا الآن نوضح كيفية إضافة الكلمات في القائمة واستخدام وظائف البحث للبحث في ال Trie.
إدراج (Insert):
لإدراج كلمة App في قائمتنا ، نحتاج ان نمر على كل الحروف في الكلمة (Loop) وفي كل حرف نتحقق مما إذا كان هناك TrieNode موجود حتى نستطيع استعمال العقدة ونستمر ، أو ننشئ TrieNode جديدًا للحرف المحدد.
خطوات:
- إنشاء متغير
nodeللوصول إلى العقد في القائمة. - نمر على كل الحروف (Loop) في كلمة App.
- تحقق مما إذا كان الحرف موجودًا في القائمة.
- إذا لم يكن الحرف موجودًا ، فقم بإنشاء
TrieNode
- إذا لم يكن الحرف موجودًا ، فقم بإنشاء
- الدخول في عقدة الحرف التالي.
- قم بتعيين عقدة الحرف الأخير
isEndإلىTrue.
TYPESCRIPTinsert(word: string): void {
let node = this.list
for (const char of word) {
if (!node[char]){
node[char] = new TrieNode()
}
node = node[char]
}
node.isEnd = true
}بحث (Search):
يمكننا اتباع نفس نمط إدراج الكلمة ولكن أثناء البحث علينا التحقق من كل حرف إذا كان هناك TrieNode أم لا وإذا لم يكن هناك يمكننا استرجاع return false على الفور.
خطوات:
- إنشاء متغير
nodeللوصول إلى العقد في القائمة. - نمر على كل الحروف في الكلمة (Loop).
- تحقق مما إذا كان الحرف موجودًا في القائمة.
- إذا لم يكن الحرف موجودًا ، فارجع
False
- إذا لم يكن الحرف موجودًا ، فارجع
- الدخول في عقدة الحرف التالي.
- إرجاع
Trueإذا كانisEndفي عقدة الحرف الأخير هياTrueواذا لا نرجعFalse.
TYPESCRIPTsearch(word: string): boolean {
let node = this.list
for (const char of word) {
if (!node[char]) return false
node = node[char]
}
return node.isEnd
}يبدأ ب (StartsWith):
يمكننا اتباع خطوات دالة Search بالضبط ولكن في النهاية سنعيد True سواء كانت هناك كلمة في نهاية السلسلة او لا.
خطوات:
- إنشاء متغير
nodeللوصول إلى العقد في القائمة. - نمر على كل الحروف في الكلمة (Loop).
- تحقق مما إذا كان الحرف موجودًا في القائمة.
- إذا لم يكن الحرف موجودًا ، فارجع
False
- إذا لم يكن الحرف موجودًا ، فارجع
- الدخول في عقدة الحرف التالي.
- إرجاع
True.
TYPESCRIPT startsWith(prefix: string): boolean {
let node = this.list
for (const char of prefix){
if (!node[char]) return false
node = node[char]
}
return true
}


