Hash tables · جداول التجزئة
Hash tables: fast lookup
- A hash table stores items so you can find them very fast — usually in one step.
- It is a list of slots. A hash function turns a key into a slot number.
- Instead of searching every item, you jump straight to the slot the key belongs in.
جداول التجزئة: بحث سريع
- جدول التجزئة يخزن عناصرًا يمكنك العثور عليها بسرعة كبيرة — عادةً في خطوة واحدة.
- هو قائمة من الخانات. دالة التجزئة تحول المفتاح إلى رقم خانة.
- بدلاً من البحث في كل عنصر، تقفز مباشرة إلى الخانة التي ينتمي إليها المفتاح.
A hash function
- A hash function takes a key and returns a slot index from
0tosize - 1. - The same key always gives the same slot, so you can find it again later.
- A simple one: add the character codes, then take
% sizeto stay in range.
دالة تجزئة
- دالة التجزئة تأخذ مفتاحًا وترجع فهرس خانة من
0إلىsize - 1. - نفس المفتاح يعطي دائمًا نفس الخانة، حتى تتمكن من العثور عليه لاحقًا.
- بسيط: اجمع رموز الأحرف، ثم خذ
% sizeللبقاء ضمن النطاق.
def hash_key(key, size):
total = 0
for ch in key:
total += ord(ch) # ord("A") is 65, ord("B") is 66, ...
return total % size
print(hash_key("cat", 10)) # a slot from 0 to 9
print(hash_key("cat", 10)) # same key -> same slot
print(hash_key("dog", 10))
Collisions
- Two different keys can hash to the same slot. That is a collision.
- A table has limited slots, so collisions are unavoidable as it fills up.
- We need a rule for what to do when the slot we want is already taken.
التصادمات
- يمكن لمفتاحين مختلفين أن يتجزأا إلى نفس الخانة. هذا تصادم.
- الجدول له عدد محدود من الخانات، لذا التصادمات لا مفر منها كلما امتلأ.
- نحتاج إلى قاعدة لما نفعله عندما تكون الخانة المطلوبة مشغولة بالفعل.
Linear probing
- Linear probing: if a slot is full, try the next slot, then the next, wrapping around.
- Keep stepping
(slot + 1) % sizeuntil you find a free slot. - Below,
AandFboth want slot 0, soFis pushed to slot 1.
المسح الخطي
- المسح الخطي: إذا كانت الخانة ممتلئة، جرب الخانة التالية، ثم التالية، مع الالتفاف حول.
- استمر في التحرك
(slot + 1) % sizeحتى تجد خانة فارغة. - بالأسفل،
AوFكلاهما يريدان الخانة 0، لذا يُدفعFإلى الخانة 1.
def hash_key(key, size):
total = 0
for ch in key:
total += ord(ch)
return total % size
def insert(table, key):
slot = hash_key(key, len(table))
while table[slot] is not None: # slot taken -> try the next one
slot = (slot + 1) % len(table)
table[slot] = key
return slot
table = [None] * 5
print(insert(table, "A")) # 0
print(insert(table, "F")) # 1 (A and F both hash to slot 0)
print(table) # ['A', 'F', None, None, None]
Looking up a key
- To find a key: hash it, then probe forward, comparing each slot to the key.
- Stop and return the index when you find it.
- If you reach an empty slot (or check every slot), the key is not there — return
-1.
البحث عن مفتاح
- لـإيجاد مفتاح: تجزئته، ثم امسح للأمام، مقارنة كل خانة بالمفتاح.
- توقف وأرجع الفهرس عند العثور عليه.
- إذا وصلت إلى خانة فارغة (أو فحصت كل خانة)، فإن المفتاح غير موجود — أرجع
-1.
Why hash tables are fast
- With few collisions, insert and find take about one step — we call this
O(1). - As the table fills, probing gets longer, so it is wise to keep some slots free.
- In the worst case (everything collides) it slows to a linear scan,
O(n).
لماذا جداول التجزئة سريعة
- مع القليل من التصادمات، الإدراج والبحث يأخذ حوالي خطوة واحدة — نسمي هذا
O(1). - كلما امتلأ الجدول، أصبح المسح أطول، لذا من الحكمة ترك بعض الخانات فارغة.
- في أسوأ الحالات (كل شيء يتصادم) يتباطأ إلى مسح خطي،
O(n).
Common mistakes
- A hash function maps a key to an index in the table.
- Two keys can collide at the same index — handle it, for example by chaining.
أخطاء شائعة
- دالة التجزئة تربط المفتاح بفهرس في الجدول.
- يمكن لمفتاحين أن يتصادما عند نفس الفهرس — تعامل معها، على سبيل المثال عن طريق السلسلة.
Now you try
- Build the three parts: the hash function, insert with probing, and find.
- Each task checks your function on collisions and wrap-around cases.
- Press Check answer to test it.
الآن جرب بنفسك
- بِنِ الثلاثة أجزاء: دالة التجزئة، الإدراج بالمسح، والبحث.
- كل مهمة تتحقق من دالتك على حالات التصادم والالتفاف حول.
- اضغط على تحقق من الإجابة لاختبارها.
Hashing to a bucket · التجزئة إلى دلو
A hash function sends each key to a bucket; clashes chain. · دالة التجزئة ترسل كل مفتاح إلى دلو؛ التصادمات تشابك.
Write hash_key(key, size). Add the character codes of key (use ord(ch)) and return the total % size, so the result is a slot from 0 to size - 1. Example: hash_key("AB", 10) is (65 + 66) % 10 = 1. The empty string gives 0. · اكتب hash_key(key, size). أضف رموز الأحرف في key (استخدم ord(ch)) وأرجع المجموع % size، بحيث يكون الناتج من فتحة 0 إلى size - 1. مثال: hash_key("AB", 10) هو (65 + 66) % 10 = 1. السلسلة الفارغة تُعطي 0.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.
hash_key is provided. Write insert(table, key) using linear probing: go to the key's hash slot; while that slot is full (not None), step to (slot + 1) % len(table); put the key in the first free slot and return its index. · hash_key مُقدَّم. اكتب insert(table, key) باستخدام الحفر الخطي: اذهب إلى فتحة تجزئة المفتاح؛ طالما أن تلك الفتحة ممتلئة (ليست None)، انتقل إلى (slot + 1) % len(table)؛ ضع المفتاح في أول فتحة فارغة وأرجع فهرسه.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.
hash_key is provided. Write find(table, key) that returns the index of key, or -1 if it is missing. Start at the hash slot and probe forward, comparing each slot. Stop at an empty slot (key not there). Make sure it ends even if the table is full — never loop forever. · hash_key مُقدَّم. اكتب find(table, key) الذي يرجع فهرس key، أو -1 إذا كان مفقوداً. ابدأ من فتحة التجزئة وحفر للأمام، ومقارنة كل فتحة. توقف عند فتحة فارغة (المفتاح غير موجود). تأكد من انتهائه حتى لو كانت الجدول ممتلئاً — لا تكرر إلى الأبد أبداً.
Click Run to see the output here. · اضغط تشغيل لرؤية المخرجات هنا.