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

Hash Map

آخر تحديث

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

هذه هي البنية وراء dict في بايثون وHashMap في جافا وMap/الكائنات في جافاسكريبت. تُعالَج التصادمات بالطريقة نفسها كما في جدول التجزئة - هنا عبر التسلسل المنفصل - لذا يعتمد الأداء على دالة تجزئة جيدة وعامل تحميل منخفض.

التعقيد الزمني

العمليةالمتوسطأسوأ حالة
إدراج/تحديث (put)O(1)O(n)
بحث (get)O(1)O(n)
حذفO(1)O(n)
المساحةO(n)O(n)

خريطة التجزئة في اللغات الشائعة

اللغةالنوع
Pythondict
JavaHashMap
JavaScriptMap / كائن
C++std::unordered_map
Gomap

مثال محلول

إدراج الأزواج ("cat", 3) و("dog", 5) و("cat", 9) و("emu", 7) في خريطة بـ 8 دلاء، باستخدام hash(key) % 8. لنفترض hash("cat") % 8 = 2 وhash("dog") % 8 = 5 وhash("emu") % 8 = 2:

الخطوةالبنيةالإجراء
Put ("cat", 3)الدلو 2: [("cat", 3)]يُجزَّأ إلى الدلو 2؛ السلسلة فارغة، لذا يُضاف الزوج.
Put ("dog", 5)الدلو 2: [("cat", 3)]، الدلو 5: [("dog", 5)]يُجزَّأ إلى الدلو 5؛ السلسلة فارغة، لذا يُضاف الزوج.
Put ("cat", 9)الدلو 2: [("cat", 9)]، الدلو 5: [("dog", 5)]يُجزَّأ إلى الدلو 2؛ المفتاح "cat" موجود بالفعل في السلسلة، لذا تُحدَّث قيمته إلى 9.
Put ("emu", 7)الدلو 2: [("cat", 9), ("emu", 7)]، الدلو 5: [("dog", 5)]يُجزَّأ إلى الدلو 2؛ يتصادم مع "cat"، ولا يُعثَر على المفتاح، لذا يُضاف الزوج.
Get "emu"الدلو 2: [("cat", 9), ("emu", 7)]يُجزَّأ إلى الدلو 2؛ تُمسَح السلسلة، ويُتخطَّى "cat"، ويطابق "emu"، وتُعاد 7.

متى تستخدم خريطة التجزئة

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

كود Hash Map

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

كود Hash Map بلغة Python

Python
1# Python's built-in dict is a hash map: O(1) average2# insert, lookup, and delete.3inventory = {"apple": 3, "banana": 7}4
5# Insert and update6inventory["cherry"] = 57inventory["apple"] += 28
9# Lookup, with .get for a safe default on missing keys10print("apple: ", inventory["apple"])11print("mango: ", inventory.get("mango", 0))12
13# Membership test and delete14print("banana in stock:", "banana" in inventory)15del inventory["banana"]16print("banana in stock:", "banana" in inventory)17
18# Iterate over key-value pairs19for fruit, count in sorted(inventory.items()):20    print(f"{fruit}: {count}")21
22# Classic hash map use case: counting frequencies23words = "the quick brown fox jumps over the lazy dog the end".split()24freq = {}25for word in words:26    freq[word] = freq.get(word, 0) + 127
28print("Occurrences of the:", freq["the"])29print("Most common word:  ", max(freq, key=freq.get))
شغّل هذا الكود في ساحة تجربة Python

الأسئلة الشائعة حول خريطة التجزئة

ما الفرق بين خريطة التجزئة وجدول التجزئة؟
هما في الأساس البنية نفسها - مصفوفة من الدلاء يُعنوَن إليها عبر تجزئة المفتاح. في الاستخدام الشائع، غالبًا ما يشير "جدول التجزئة" إلى مجموعة مفاتيح أو إلى الأسلوب العام، بينما تُبرز "خريطة التجزئة" تخزين أزواج المفتاح-القيمة. تُميّز بعض اللغات أيضًا من حيث الأمان مع الخيوط (مثل Hashtable و HashMap في جافا)، لكن الخوارزمية الأساسية متطابقة.
ما هو التعقيد الزمني لخريطة التجزئة؟
عمليات put و get و delete هي O(1) في المتوسط مع دالة تجزئة جيدة وعامل تحميل منخفض. في الحالة المرضية التي تتصادم فيها جميع المفاتيح في دلو واحد، تتدهور إلى O(n)، ولهذا يهم إعادة التحجيم والتجزئة الجيدة.
كيف تتعامل خريطة التجزئة مع مفتاحين يُجزَّآن إلى الدلو نفسه؟
تحلّ التصادم. يستخدم هذا التمثيل المرئي التسلسل المنفصل: يحمل كل دلو قائمة صغيرة، ويُضاف الزوج الجديد الذي يُجزَّأ مفتاحه هناك إلى تلك القائمة. عند البحث، تمسح الخريطة السلسلة القصيرة بحثًا عن المفتاح المطابق. الأسلوب البديل هو العنونة المفتوحة، التي تسبر خانة أخرى في المصفوفة.
خريطة التجزئة أم شجرة البحث الثنائية: أيهما أستخدم؟
استخدم خريطة التجزئة عندما تحتاج فقط إلى البحث بمفتاح دقيق وتريد عمليات بمتوسط O(1). استخدم شجرة بحث ثنائية متوازنة (مثل TreeMap أو std::map) عندما تحتاج إلى مفاتيح مرتبة أو استعلامات نطاق أو عمليات بحث عن السابق/اللاحق، وتكلفتها O(log n). تُقايض الشجرة قليلًا من السرعة مقابل ضمانات ترتيب لا تستطيع خريطة التجزئة توفيرها.
ما هو عامل التحميل ولماذا يُطلق إعادة التحجيم؟
عامل التحميل هو نسبة المُدخَلات المخزَّنة إلى الدلاء. مع ارتفاعه تطول السلاسل وتبطؤ عمليات البحث المتوسطة، لذا تُعيد معظم التطبيقات التحجيم (عادةً بمضاعفة الدلاء وإعادة تجزئة كل شيء) بمجرد تجاوزه عتبة مثل 0.75. إعادة التحجيم هي O(n) لكنها نادرة، فتُستهلَك وتُبقي العمليات المتوسطة عند O(1).
هل يمكنني استخدام كائن قابل للتغيير مثل قائمة كمفتاح لخريطة التجزئة؟
عادةً لا. يجب أن تكون المفاتيح قابلة للتجزئة ويجب أن تبقى تجزئتها ثابتة طالما هي في الخريطة - يرفع بايثون TypeError: unhashable type من أجل list مثلًا. إذا غيّرت مفتاحًا بعد إدراجه، تتغير تجزئته ولا تستطيع الخريطة إيجاده بعد ذلك في الدلو الصحيح، فتفقد المُدخَل بصمت. استخدم مفاتيح غير قابلة للتغيير مثل السلاسل أو الأرقام أو الصفوف.
Coddy programming languages illustration

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

ابدأ الآن