مرتبسازی سریع
آخرین عضو را محور میگیرد، کوچکترها را به چپ و بزرگترها را به راستش میبرد و هر طرف را بهصورت بازگشتی مرتب میکند.
مرتبسازی سریع هم «تقسیم و حل» است، ولی کار اصلی را قبل از بازگشت انجام میدهد:
ادامهی توضیح ↓- زمان:
O(n log n) on average, O(n²) at worst - حافظه:
O(log n) stack on average - CLRS، بخش ۷.۱
- هوروویتز–ساهنی، فصل ۷
هشت عدد درهم با محور ۴ در دور اول؛ ۱۵ مقایسه.
def quick_sort(a):sort(a, 0, len(a) - 1)return adef sort(a, lo, hi):if lo >= hi:returnp = partition(a, lo, hi)sort(a, lo, p - 1)sort(a, p + 1, hi)def partition(a, lo, hi):pivot = a[hi]i = lo - 1for j in range(lo, hi):if a[j] <= pivot:i = i + 1a[i], a[j] = a[j], a[i]a[i + 1], a[hi] = a[hi], a[i + 1]return i + 1
شروع اجرا
درخت فراخوانیهای بازگشتی
نارنجی پر = فراخوانی در حال اجرا · حاشیهی نارنجی = هنوز روی پشته · خاکستری = تمام شده
متغیرهای محلی
نارنجی = در همین گام عوض شد
a list
28713564
Call stack
- quick_sort()خط 1
گام ۱ از ۱۲۴
رشد تعداد عملیات با اندازهی ورودی
میانگین ۱۲ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.
- comparisons
- swaps
- place
- ورودی فعلی (n=8)
نمایش به شکل جدول
| n | comparisons | swaps | place |
|---|---|---|---|
| 4 | 4.7 | 2.5 | 2.3 |
| 6 | 9.8 | 4.4 | 3.6 |
| 8 | 17.4 | 8.3 | 5.1 |
| 10 | 25.5 | 14.2 | 6.6 |
| 12 | 32.4 | 17.8 | 7.5 |
| 14 | 41.3 | 24.3 | 8.8 |
| 16 | 52.5 | 29.2 | 10.6 |
توضیح
ایده
مرتبسازی سریع هم «تقسیم و حل» است، ولی کار اصلی را قبل از بازگشت انجام میدهد:
- یک عضو را محور (
pivot) بگیر؛ اینجا آخرین عضو بازه،a[hi]. - بازه را افراز کن: عضوهای
≤ pivotبه چپ و بقیه به راست بروند، و محور بین آنها در جای نهاییاش بنشیند. - دو طرف محور را بهصورت بازگشتی مرتب کن. ترکیب لازم نیست، چون آرایه درجا مرتب شده است.
افراز (روش لوموتو)
i مرز بخش «کوچکترها» است. j از lo تا hi − 1 جلو میرود؛ هر جا a[j] ≤ pivot بود، i یکی جلو میرود و a[i] و a[j] جابهجا میشوند. در پایان، محور با a[i + 1] جابهجا میشود.
هزینه
- اگر محور هر بار بازه را تقریباً نصف کند، عمق بازگشت
log nو زمانO(n log n)است. این حالت متوسط هم هست. - اگر محور همیشه بزرگترین یا کوچکترین باشد (مثلاً روی آرایهی مرتب)، یک طرف خالی میماند و زمان
O(n²)میشود. - عضوهای تکراری هم با این روش افراز نامتوازن میسازند؛ ورودی «همه برابر» را ببین.
- انتخاب تصادفی محور این خطر را کم میکند، ولی اینجا برای اینکه هر اجرا یکسان باشد، محور ثابت (آخرین عضو) است.
در trace به چه چیزی نگاه کنی
pivotبالای آرایه نوشته شده و نوار آبی بازهیlo..hiاست. فلشهایiوjمرزهای افرازند.- در «درخت فراخوانیهای بازگشتی»، شکل درخت را برای «بهترین حالت» و «بدترین حالت» مقایسه کن: یکی پهن و کوتاه، دیگری یک زنجیر بلند.