AlgoVerse

جستجوی دودویی

در آرایه‌ی مرتب، هر بار عضو وسط بازه را با مقدار مورد جستجو مقایسه می‌کند و نیمی از بازه را کنار می‌گذارد.

جستجوی دودویی فقط روی آرایه‌ی مرتب کار می‌کند. بازه‌ی a[low..high] جایی است که target ممکن است باشد. در هر دور عضو وسط، a[mid]، را نگاه کن:

ادامه‌ی توضیح ↓
ورودی:
n=10 · target=9خروجی PDF

ده عدد مرتب؛ ۹ بعد از سه بار نصف کردن بازه پیدا می‌شود.

  1. def binary_search(a, target):
  2. low = 0
  3. high = len(a) - 1
  4. while low <= high:
  5. mid = (low + high) // 2
  6. if a[mid] == target:
  7. return mid
  8. if a[mid] < target:
  9. low = mid + 1
  10. else:
  11. high = mid - 1
  12. return -1

ناوردا: اگر target در آرایه باشد، در بازه‌ی a[low..high] است.

شروع اجرا

target 9103142638495116147178209

متغیرهای محلی

target9

نارنجی = در همین گام عوض شد

a list

13468911141720

Call stack

  1. binary_search()خط 1
گام ۱ از ۱۷
خط سیاه = probe · خط نارنجی = گام کلیدیcompare: 0/5 · probe: 0/3 · go_right: 0/1 · go_left: 0/1 · found: 0/1

    رشد تعداد عملیات با اندازه‌ی ورودی

    میانگین ۱۲ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.

    • comparisons
    • probe
    • ورودی فعلی (n=10)
    0246846810121416n = تعداد عضوهای آرایهcomparisonsprobe
    نمایش به شکل جدول
    ncomparisonsprobe
    43.62.1
    64.82.7
    84.92.8
    105.12.8
    126.53.6
    1463.3
    165.63.1
    توضیح

    ایده

    جستجوی دودویی فقط روی آرایه‌ی مرتب کار می‌کند. بازه‌ی a[low..high] جایی است که target ممکن است باشد. در هر دور عضو وسط، a[mid]، را نگاه کن:

    • اگر برابر target بود، پیدا شد.
    • اگر کوچک‌تر بود، target فقط می‌تواند در نیمه‌ی راست باشد: low = mid + 1.
    • اگر بزرگ‌تر بود، فقط در نیمه‌ی چپ: high = mid − 1.

    وقتی low > high شد، بازه خالی است و target در آرایه نیست؛ تابع −1 برمی‌گرداند.

    هزینه

    هر دور اندازه‌ی بازه را نصف می‌کند، پس حداکثر ⌊log₂ n⌋ + 1 دور لازم است: برای هزار عضو حداکثر ۱۰ دور، برای یک میلیون عضو ۲۰ دور. حافظه‌ی اضافه O(1) است.

    چرا آرایه باید مرتب باشد؟

    کنار گذاشتن نیمی از بازه فقط وقتی درست است که بدانیم همه‌ی عضوهای سمت چپ a[mid] کوچک‌تر یا مساوی و همه‌ی عضوهای سمت راست بزرگ‌تر یا مساوی‌اند. اعتبارسنج ورودی آرایه‌ی نامرتب را قبول نمی‌کند.

    در trace به چه چیزی نگاه کنی

    • نوار آبی بازه‌ی low..high است و خط چین آبی ارتفاع target را نشان می‌دهد.
    • فلش‌های low، mid و high زیر میله‌ها جابه‌جا می‌شوند؛ ببین بازه در هر دور نصف می‌شود.
    • ورودی «target تکراری» نشان می‌دهد که این نسخه لزوماً اولین تکرار را پیدا نمی‌کند.