جدول درهمسازی با کاوش خطی
هر کلید در خانهی key mod m مینشیند؛ اگر پر بود، خانههای بعدی را یکییکی امتحان میکند تا جای خالی پیدا شود.
جدول درهمسازی کلیدها را در آرایهای به اندازهی m نگه میدارد و جای هر کلید را با یک تابع درهمسازی حساب میکند؛ اینجا h(k) = k mod m. اگر آن خانه پر بود (برخورد)، در «آدرسدهی باز» خانهی دیگری از خود جدول امتحان میشود. در کاوش خطی، خانههای h(k)+1، h(k)+2، … به ترتیب امتحان میشوند.
- زمان:
O(1) per insert on average when the table is not too full - حافظه:
O(m) - CLRS، بخش ۱۱.۴
- هوروویتز–ساهنی، فصل ۸
- جانسونباو، فصل ۳
نُه کلید در جدول ۱۱ خانهای؛ چند برخورد پیش میآید و کلیدها کنار هم خوشه میسازند.
def hash_insert_all(keys):m = 11table = [None] * mfor key in keys:i = 0while True:j = (key + i) % mif table[j] is None:table[j] = keybreaki = i + 1return table
شروع اجرا
متغیرهای محلی
نارنجی = در همین گام عوض شد
keys list
Call stack
- hash_insert_all()خط 1
رشد تعداد عملیات با اندازهی ورودی
میانگین ۱۲ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.
- collision
- ورودی فعلی (n=9)
نمایش به شکل جدول
| n | collision |
|---|---|
| 4 | 0.3 |
| 6 | 2.6 |
| 8 | 3.9 |
| 10 | 11 |
توضیح
ایده
جدول درهمسازی کلیدها را در آرایهای به اندازهی m نگه میدارد و جای هر کلید را با یک تابع درهمسازی حساب میکند؛ اینجا h(k) = k mod m. اگر آن خانه پر بود (برخورد)، در «آدرسدهی باز» خانهی دیگری از خود جدول امتحان میشود. در کاوش خطی، خانههای h(k)+1، h(k)+2، … به ترتیب امتحان میشوند.
خوشهبندی اولیه
کاوش خطی ساده است ولی یک ضعف دارد: کلیدها پشت سر هم خوشه میسازند و هر کلیدی که به هر جای خوشه برسد، باید تا انتهای آن برود؛ پس خوشهها بزرگتر و بزرگتر میشوند. ورودی «یک خوشه» این را نشان میدهد. کاوش مربعی و درهمسازی دوگانه این مشکل را کم میکنند.
هزینه
اگر جدول خیلی پر نباشد (ضریب بار α = n/m کمتر از حدود ۰٫۷)، هر درج بهطور متوسط O(1) کاوش دارد. با پر شدن جدول، تعداد کاوشها تند بالا میرود.
در trace به چه چیزی نگاه کنی
- خانههای خطچین خالیاند؛
keyبالای جدول کلیدی است که درج میشود و فلشjخانهی در حال کاوش. - شمار
collisionرا در «بدون برخورد»، «مثال به سبک کتاب» و «یک خوشه» مقایسه کن.