freeCodeCamp/guide/arabic/computer-science/data-structures/hash-tables/index.md

7.8 KiB

title localeTitle
Hash Tables جداول تجزئة

جداول تجزئة

جدول التجزئة (أو خريطة التجزئة) عبارة عن بنية بيانات يمكنها تعيين مفاتيح للقيم. يستخدم جدول التجزئة جدول دالة لحساب فهرس إلى مجموعة من الدلاء ، التي يمكن العثور على القيم المطلوبة. يمكن أن يكون تعقيد وقت وظيفة هاش محددة بوضوح O (1).

جدول التجزئة (مخطط التجزئة) هو هيكل بيانات يقوم بتنفيذ نوع بيانات تجريدى لمجموعة صفية ، وهي بنية يمكنها تعيين مفاتيح للقيم. يستخدم جدول هاش وظيفة دالة لحساب فهرس في مجموعة من الدلاء أو الفتحات ، والتي يمكن العثور على القيمة المطلوبة منها.

مثال لجدول هاش

بعض الخصائص الهامة لجدول Hash - 1) لا يتم تخزين القيم بترتيب مفروض. 2) في جدول تجزئة ، يجب على المرء أيضا التعامل مع التصادم المحتملة. ويتم ذلك غالبًا عن طريق الربط ، وهو ما يعني إنشاء قائمة مرتبطة بجميع القيم التي يتم تعيين مفاتيحها إلى فهرس معين.

تنفيذ جدول التجزئة

يتم تطبيق جدول تجزئة تقليديًا مع مجموعة من القوائم المرتبطة. عندما نريد إدراج زوج مفتاح / قيمة ، نقوم بتعيين المفتاح إلى فهرس في الصفيف باستخدام وظيفة التجزئة. ثم يتم إدخال القيمة في القائمة المرتبطة في هذا الموضع.

تتمثل فكرة التجزئة في توزيع المدخلات (أزواج المفاتيح / القيم) عبر مجموعة من المجموعات. عند الحصول على مفتاح ، تقوم الخوارزمية بحساب فهرس يشير إلى المكان الذي يمكن العثور فيه على الإدخال:

index = f(key, array_size)

يتم ذلك غالبًا في خطوتين:

hash = hashfunc(key) index = hash % array_size

في هذه الطريقة ، يكون التجزئة مستقلاً عن حجم الصفيف ، ثم يتم تخفيضه إلى فهرس (رقم بين 0 و array_size - 1) باستخدام مشغل modulo (٪).

دعنا نفكر في السلسلة S. أنت مطالب بحساب معدل تكرار جميع الأحرف في هذه السلسلة.

string S = “ababcd”

إن أبسط طريقة للقيام بذلك هي التكرار على جميع الأحرف الممكنة وحساب ترددها واحدة تلو الأخرى. وقت تعقيد هذا الأسلوب هو O (26 * N) حيث N هو حجم السلسلة ويوجد 26 حرفًا محتملًا.

void countFre(string S) { for(char c = 'a';c <= 'z';++c) { int frequency = 0; for(int i = 0;i < S.length();++i) if(S[i] == c) frequency++; cout << c << ' ' << frequency << endl; } }

انتاج |

a 2 b 2 c 1 d 1 e 0 f 0 … z 0

دعونا نطبق التجزئة على هذه المشكلة. خذ تردد صفيف من حجم 26 و تجزئة الأحرف 26 مع مؤشرات الصفيف باستخدام دالة التجزئة. ثم ، التكرار فوق السلسلة وزيادة القيمة في التردد في الفهرس المقابل لكل حرف. تعقيد هذا الأسلوب هو O (N) حيث N هو حجم السلسلة.

`int Frequency[26];

int hashFunc(char c) 
{ 
    return (c - 'a'); 
} 

void countFre(string S) 
{ 
    for(int i = 0;i < S.length();++i) 
    { 
        int index = hashFunc(S[i]); 
        Frequency[index]++; 
    } 
    for(int i = 0;i < 26;++i) 
        cout << (char)(i+'a') << ' ' << Frequency[i] << endl; 
} 

`

انتاج |

a 2 b 2 c 1 d 1 e 0 f 0 … z 0

تصادم تجزئة

عندما تستخدم خريطة تجزئة ، عليك أن تفترض أن تصادمات التجزئة لا يمكن تجنبها ، لأنك ستستخدم خريطة تجزئة أصغر حجماً بكثير من حجم البيانات المتوفرة لديك. النهجان الرئيسيان لحل هذه الاصطدامات هما Chaining و Open Addressing.

تسلسل

إحدى الطرق التي يمكنك بها حل تصادمات التجزئة هي استخدام التسلسل. ما يعنيه هذا بالنسبة لكل تعيين قيمة مفتاح في جدول التجزئة ، لن يحتفظ حقل القيمة بخلية بيانات واحدة فقط ، بل قائمة بيانات مرتبطة. في المثال الموضح في الصورة أدناه ، يمكنك رؤية أن Sandra Dee تمت إضافته كعنصر آخر للمفتاح 152 بعد John Smith.

مثال على تسلسل في جدول تجزئة

النكسة الرئيسية فيما يتعلق تسلسل هو زيادة في تعقيد الوقت. وهذا يعني أنه بدلاً من خصائص O (1) لجدول التجزئة العادي ، فإن كل إجراء سيستغرق الآن وقتًا أطول لأننا نحتاج إلى اجتياز القائمة المرتبطة.

فتح العنونة

هناك طريقة أخرى يمكنك من خلالها حل تصادمات التجزئة باستخدام العنونة المفتوحة. في هذه الطريقة بمجرد تعيين قيمة إلى مفتاح مشغول بالفعل ، تنتقل على طول المفاتيح المجاورة لجدول التجزئة بطريقة محددة مسبقًا ، حتى تجد مفتاحًا ذا قيمة فارغة. في المثال الموضح في الصورة أدناه ، يتم تعيين Sandra Dee على المفتاح 153 ، على الرغم من أنه من المفترض أن يتم تعيين قيمته إلى 152.

مثال على عنونة مفتوحة في جدول تجزئة

تكمن النكسة الرئيسية للعنونة المفتوحة في حقيقة أنه عندما تكون هناك حاجة للبحث عن قيم ، فقد لا تكون في المكان الذي تتوقع أن يكون عليه (رسم المفاتيح). لذلك عليك اجتياز أجزاء من جدول التجزئة للعثور على القيمة التي تبحث عنها ، مما يؤدي إلى زيادة تعقيد الوقت.

تعقيد الوقت

من المهم جداً ملاحظة أن جداول التجزئة قد استهلكت التعقيد المستمر ، أي في حالة متوسطة سيكون التعقيد O (1). في أسوأ الحالات ، إذا تم تجزئ الكثير من العناصر إلى نفس المفتاح ، يمكن أن يكون هناك تعقيد زمني لـ O (n).

معلومات اكثر:

مزيد من المعلومات عن الجداول تجزئة - الويكي مقارنة بين Hash Table و STL-map

مصدر

أساسيات الجداول تجزئة - هاكر