AlgoVerse

ادغام k-راهه

k دنباله‌ی مرتب را با یک هیپ کمینه هم‌زمان ادغام می‌کند: هر بار کوچک‌ترینِ سرِ دنباله‌ها را برمی‌دارد. پایه‌ی مرتب‌سازی خارجی.

k دنباله‌ی مرتب داریم و می‌خواهیم یک دنباله‌ی مرتب بسازیم. کوچک‌ترین عضو کل، حتماً سرِ یکی از دنباله‌هاست. پس سرهای همه‌ی دنباله‌ها را در یک هیپ کمینه می‌گذاریم:

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

سه دنباله‌ی مرتب پشت سر هم: (۳ ۹ ۱۴)، (۱ ۸ ۲۰ ۲۵) و (۵ ۶ ۱۲)؛ هیپ همیشه سه عضو دارد تا یکی تمام شود.

  1. import heapq
  2. def k_way_merge(a):
  3. # The sorted runs of a, found by scanning for descents.
  4. runs = []
  5. start = 0
  6. for i in range(1, len(a) + 1):
  7. if i == len(a) or a[i] < a[i - 1]:
  8. runs.append(a[start:i])
  9. start = i
  10. # A min-heap holds the front item of every run: (value, run, position).
  11. heap = [(run[0], r, 0) for r, run in enumerate(runs)]
  12. heapq.heapify(heap)
  13. out = []
  14. while heap:
  15. value, r, i = heapq.heappop(heap)
  16. out.append(value)
  17. if i + 1 < len(runs[r]):
  18. heapq.heappush(heap, (runs[r][i + 1], r, i + 1))
  19. return out

ناوردا: هیپ همیشه کوچک‌ترین عضوِ برداشته‌نشده‌ی هر دنباله را دارد، پس کوچک‌ترینِ هیپ کوچک‌ترینِ همه‌ی باقی‌مانده‌هاست.

شروع اجرا

value—
out—

جدول هنوز خالی است.

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

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

a list

39141820255612

Call stack

  1. k_way_merge()خط 4
گام ۱ از ۸۲
خط سیاه = take · خط نارنجی = گام کلیدیrun: 0/3 · heap_ready: 0/1 · take: 0/10 · refill: 0/7
    توضیح

    ایده

    k دنباله‌ی مرتب داریم و می‌خواهیم یک دنباله‌ی مرتب بسازیم. کوچک‌ترین عضو کل، حتماً سرِ یکی از دنباله‌هاست. پس سرهای همه‌ی دنباله‌ها را در یک هیپ کمینه می‌گذاریم:

    1. کوچک‌ترین را بردار و به خروجی اضافه کن.
    2. عضو بعدیِ همان دنباله را وارد هیپ کن.

    هزینه

    هر عضو یک بار وارد و یک بار خارج هیپ k عضوی می‌شود: O(n log k). بدون هیپ، پیدا کردن کوچک‌ترینِ k سر هر بار O(k) بود.

    کاربرد

    مرتب‌سازی خارجی: داده‌ای که در حافظه جا نمی‌شود را تکه‌تکه مرتب می‌کنند و روی دیسک می‌نویسند، بعد همه‌ی تکه‌ها را با ادغام k-راهه یکی می‌کنند. اینجا دنباله‌ها همان تکه‌های مرتبِ آرایه‌ی ورودی‌اند.

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

    • هر سطر جدول یک دنباله است؛ out در کارت بالا خروجی تا اینجاست و heap در پنل حافظه.