AlgoVerse

مرتب‌سازی شل

مرتب‌سازی درجی روی عضوهایی که gap خانه از هم فاصله دارند، با gapهای کوچک‌شونده تا ۱؛ عضوهای دور زود به جای درستشان نزدیک می‌شوند.

مرتب‌سازی درجی روی آرایه‌ی تقریباً مرتب خیلی سریع است، ولی عضوی که از جای درستش دور است باید یکی‌یکی خانه‌ها را طی کند. شل این مشکل را با gap حل می‌کند: اول عضوهایی را که gap خانه از هم فاصله دارند با مرتب‌سازی درجی مرتب می‌کند، تا عضوها با جهش‌های بلند به جای تقریبی‌شان برسند. بعد gap را نصف می‌کند و دوباره، تا gap = 1 که همان مرتب‌سازی درجی معمولی است، ولی روی آرایه‌ای که تقریباً مرتب شده.

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

هشت عدد درهم: gapها ۴، ۲ و ۱.

  1. def shell_sort(a):
  2. gap = len(a) // 2
  3. while gap > 0:
  4. for j in range(gap, len(a)):
  5. key = a[j]
  6. i = j - gap
  7. while i >= 0:
  8. if a[i] <= key:
  9. break
  10. a[i + gap] = a[i]
  11. i = i - gap
  12. a[i + gap] = key
  13. gap = gap // 2
  14. return a

ناوردا: بعد از دوری که با gap = g انجام شد، هر زیردنباله‌ی a[k], a[k+g], a[k+2g], … مرتب است.

شروع اجرا

350331422103144195276447

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

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

a list

3533421014192744

Call stack

  1. shell_sort()خط 1
گام ۱ از ۱۵۰
خط سیاه = gap · خط نارنجی = گام کلیدیcompare: 0/19 · gap: 0/4 · pick: 0/17 · shift: 0/7 · insert: 0/17

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

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

    • comparisons
    • shift
    • insert
    • ورودی فعلی (n=8)
    02040608046810121416n = تعداد عضوهای آرایهcomparisonsinsertshift
    نمایش به شکل جدول
    ncomparisonsshiftinsert
    462.85
    611.65.98
    821.1717
    1029.111.322
    1237.816.726
    144419.431
    1668.726.849
    توضیح

    ایده

    مرتب‌سازی درجی روی آرایه‌ی تقریباً مرتب خیلی سریع است، ولی عضوی که از جای درستش دور است باید یکی‌یکی خانه‌ها را طی کند. شل این مشکل را با gap حل می‌کند: اول عضوهایی را که gap خانه از هم فاصله دارند با مرتب‌سازی درجی مرتب می‌کند، تا عضوها با جهش‌های بلند به جای تقریبی‌شان برسند. بعد gap را نصف می‌کند و دوباره، تا gap = 1 که همان مرتب‌سازی درجی معمولی است، ولی روی آرایه‌ای که تقریباً مرتب شده.

    هزینه

    • با gapهای n/2, n/4, …, 1 بدترین حالت O(n²) است، ولی در عمل خیلی بهتر از مرتب‌سازی درجی کار می‌کند.
    • با دنباله‌های بهتر (مثلاً 1, 4, 13, 40, …) زمان به حدود O(n^1.5) می‌رسد.
    • حافظه‌ی اضافه O(1)؛ پایدار نیست.

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

    • با سطح جزئیات «هر دور حلقه» فقط تغییر gap را ببین.
    • ورودی «برعکس مرتب» را با مرتب‌سازی درجی روی همان ورودی مقایسه کن (شمار shift).