در علوم رایانه، **مرتب‌سازی ادغام-درج** یا الگوریتم فورد-جانسون از الگوریتم‌های مرتب‌سازی مقایسه‌ای است که در سال ۱۹۵۹ توسط لستر رادولف فورد و سلمر مارتین جانسون منتشر شد. این الگوریتم از الگوریتم‌های شناخته شده قبلی همچون مرتب‌سازی درجی دودویی و مرتب‌سازی ادغامی در بدترین حالت، از تعداد مقایسه‌های کمتری استفاده می‌کند.

مشخص است که کم بودن تعداد مقایسه‌ها معیاری مناسب برای اثربخشی یک الگوریتم مرتب‌سازی نیست؛ امّا از دیدگاه نظری کمینه کردن تعداد مقایسه‌ها در مسائل مرتب‌سازی همواره مهم بوده‌است. همین الگوریتم توسط ریاضیدان لهستانی به‌طور مستقل کشف شد.

مقدمه ای بر الگوریتم
--------------------

فرض می‌کنیم ۵ عدد داریم ({\displaystyle a,b,c,d,e})، آن‌ها را به سه دسته تقسیم می‌کنیم: {\displaystyle (a,b)(c,d)(e)}

سپس دو عدد موجود در دسته‌های دوتایی را باهم مقایسه می‌کنیم و بعد از آن دو عدد بزرگتر هر دسته را با یکدیگر مقایسه می‌کنیم. فرض می‌کنیم {\displaystyle a>b,c>d}. آنگاه باید دو عدد {\displaystyle a,c} را با هم مقایسه کنیم. در شکل‌های زیر جهت پیکان از عدد کوچکتر به سمت عدد بزرگتر است.  

با توجه به شکل بالا داریم {\displaystyle b<a<c}. اکنون باید عنصر e را بین این سه عنصر مرتب شده درج کنیم که با دو مقایسه امکان‌پذیر است. (مرتب‌سازی درجی دودویی) سپس بعد از معلوم شدن جایگاه e، عنصر d را در صف مرتب شده درج می‌کنیم که آن نیز با دو مقایسه امکان‌پذیر است.

الگوریتم
--------

الگوریتم فورد-جانسون یا مرتب‌سازی ادغام-درج تعمیم جالبی از مقدمه بالاست. مراحل این الگوریتم به شرح زیر است:

### ادغام

1. n عنصر موجود را به {\displaystyle \left\lfloor {\frac {n}{2}}\right\rfloor } گروه دوتایی تقسیم می‌کنیم؛ و اگر n فرد بود، یک عنصر جفت نشده باقی می‌ماند.
2. {\displaystyle \left\lfloor {\frac {n}{2}}\right\rfloor }مقایسه انجام می‌دهیم تا عنصر بزرگتر در هر گروه را بیابیم.
3. {\displaystyle \left\lfloor {\frac {n}{2}}\right\rfloor } عنصر بزرگتر را به شکل بازگشتی مرتب می‌کنیم. حال عناصر مرتب شده را زنجیره اصلی می‌نامیم که به صورت a\_{i}در شکل نمایش داده شده‌است.
4. سپس با توجه به این که زنجیره اصلی مرتب شده‌است و عنصر {\displaystyle a\_{1}} کوچکترین عنصر زنجیره است و می‌دانیم {\displaystyle b\_{1}} از آن کوچکتر است، بنابراین می‌توان {\displaystyle b\_{1}} را در ابتدای زنجیره درج نمود.
5. بقیه عناصر که به شکل {\displaystyle b\_{i}} نشان داده شده‌است را در زنجیره اصلی درج می‌کنیم. (با استفاده از مرتب‌سازی درجی)

### درج

روش درج کردن {\displaystyle b\_{i}}ها به ترتیب زیر است:

{\displaystyle b\_{3},b\_{2};b\_{5},b\_{4};b\_{1}1,b\_{1}0,...b\_{6};.....;b\_{t\_{k}},b\_{t\_{k-1}},......b\_{t\_{k-1}}+1}

{\displaystyle (t\_{1},t\_{2},t\_{3},t\_{4},...)=(1,3,5,11,...)}

سپس در آخر در صورت وجود، {\displaystyle b\_{{\left\lfloor {\frac {n}{2}}\right\rfloor }+1}} را در زنجیره اصلی درج می‌نماییم.

تحلیل الگوریتم
--------------

برای بررسی تعداد مقایسه‌ها ابتدا به مقادیر {\displaystyle t\_{k}}ها می‌پردازیم. این مقادیر باید باید به گونه‌ای باشند که تعداد عناصر زنجیره اصلی هنگام درج یک عنصر در مرحله {\displaystyle k}ام برابر {\displaystyle 2^{k}-1}باشد.

در نتیجه داریم:

{\displaystyle 2t\_{k-1}+(t\_{k}-t\_{k-1})-1=2^{k}-1\Longrightarrow t\_{k}+t\_{k-1}=2^{k},t\_{1}=1}

با حل رابطه بازگشتی بالا به جواب زیر می‌رسیم:

{\displaystyle t\_{k}={\frac {1}{3}}(2^{k+1}+(-1)^{k})}

{\displaystyle F(n)}را تعداد مقایسه‌های الگوریتم فورد-جانسون برای {\displaystyle n}عنصر می‌گیریم. ابتدا {\displaystyle \left\lfloor {\frac {n}{2}}\right\rfloor }مقایسه برای پیدا کردن عنصر بزرگتر در هر دسته داریم و سپس زنجیره اصلی را به شکل بازگشتی مرتب می‌کنیم و {\displaystyle G}هم تعداد مقایسه‌ها برای درج عناصر کوچکتر دسته‌ها در زنجیره اصلی است.

{\displaystyle F(n)=\left\lfloor {\frac {n}{2}}\right\rfloor +F({\left\lfloor {\frac {n}{2}}\right\rfloor })+G({\left\lceil {\frac {n}{2}}\right\rceil })}

و برای هر {\displaystyle t\_{k-1}\leq n\leq t\_{k}}،{\displaystyle G(n)}برابر است با {\displaystyle \sum \_{j=1}^{k-1}[j(t\_{j}-t\_{j-1})]+k(n-t\_{k-1})}.

{\displaystyle \sum \_{j=1}^{k-1}[j(t\_{j}-t\_{j-1})]+k(n-t\_{k-1})=kn-(t\_{0}+t\_{1}+t\_{2}+...+t\_{k-1})}

{\displaystyle w\_{k}=t\_{0}+t\_{1}+t\_{2}+...+t\_{k-1}\Longrightarrow (w\_{0},w\_{1},w\_{2},w\_{3},...)=(0,1,2,5,...)}

پس از تعریف {\displaystyle w\_{k}}به شکل بالا می‌توان ثابت کرد : {\displaystyle F(n)-F(n-1)=k\Longleftrightarrow w\_{k}<n\leq w\_{k+1}}

و شرط بالا معادل است با : {\displaystyle {\frac {2^{k+1}}{3}}<n<{\frac {2^{k+2}}{3}}\Longrightarrow k+1<log(3n)\leq k+2}

بنابرابن داریم : {\displaystyle F(n)-F(n-1)=\left\lceil log({\frac {3}{4}}n)\right\rceil }

در نتیجه: {\displaystyle F(n)=\sum \_{k=1}^{n}\left\lceil log({\frac {3}{4}}k)\right\rceil }

مقایسه با سایر الگوریتم‌ها
--------------------------

نام این الگوریتم ادغام-درج است زیرا مقایسه‌های اولیه که قبل از فراخوانی بازگشتی انجام می‌شود، همچون مقایسه‌های الگوریتم مرتب‌سازی ادغامی است و همچنین مقایسه‌هایی که بعد از فراخوانی بازگشتی صورت می‌گیرد، مانند الگوریتم مرتب‌سازی درجی دودویی است. در واقع می‌توان الگوریتم فورد-جانسون را الگوریتم چندگانه نامید زیرا تلفیقی از دو مرتب‌سازی درجی و ادغامی است.

تعداد مقایسه‌های این الگوریتم مرتب‌سازی برای {\displaystyle n\leq 11}برابر با کران پایین تعداد مقایسه‌های مرتب‌سازی‌های مقایسه‌ای است. این کران پایین برابر است با {\displaystyle \lceil \log \_{2}n!\rceil \approx n\log \_{2}n-1.443n}

امّا تعداد مقایسه برای {\displaystyle n}های بزرگتر بیشتر از این کران پایین است.

همان‌طور که در جدول زیر دیده می‌شود، تعداد مقایسه‌ها در الگوریتم فورد-جانسون از دو الگوریتم ادغامی و درجی برای {\displaystyle n}های کوچکتر از {\displaystyle 18} کمتر است.  


تعداد مقایسه‌ها در بدترین حالت| ۱۷ | ۱۶ | ۱۵ | ۱۴ | ۱۳ | ۱۲ | ۱۱ | ۱۰ | ۹ | ۸ | ۷ | ۶ | ۵ | ۴ | ۳ | ۲ | ۱ | n |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| ۵۴ | ۴۹ | ۴۵ | ۴۱ | ۳۷ | ۳۳ | ۲۹ | ۲۵ | ۲۱ | ۱۷ | ۱۴ | ۱۱ | ۸ | ۵ | ۳ | ۱ | ۰ | مرتب‌سازی درجی |
| ۶۵ | ۴۹ | ۴۵ | ۴۱ | ۳۸ | ۳۳ | ۳۰ | ۲۷ | ۲۵ | ۱۷ | ۱۴ | ۱۱ | ۹ | ۵ | ۳ | ۱ | ۰ | مرتب‌سازی ادغامی |
| ۵۰ | ۴۶ | ۴۲ | ۳۸ | ۳۴ | ۳۰ | ۲۶ | ۲۲ | ۱۹ | ۱۶ | ۱۳ | ۱۰ | ۷ | ۵ | ۳ | ۱ | ۰ | مرتب‌سازی ادغام-درج |

الگوریتم‌های بهینه تر
---------------------

تا به امروز الگوریتم بهینه‌تر از نظر زمانی برای الگوریتم فورد-جانسون ارائه شده‌است که تعداد مقایسه‌های دقیقاً برابر فورد-جانسون است؛ امَا زمان کمتری می‌گیرد بدین گونه که به جای فراخوانی بازگشتی بر روی نصف لیست اعداد، بر روی یک چهارم لیست اعداد می‌باشد.

تا بیست سال الگوریتم فورد-جانسون، کمترین تعداد مقایسه را میان الگوریتم‌های مرتب‌سازی داشت. در سال ۱۹۷۹ گلن ماناکر الگوریتم مرتب‌سازی دیگری ارائه کرد که تعداد مقایسه‌های آن از فورد-جانسون حتی برای ورودی‌ها با تعداد زیاد نیز کمتر بود.

ماناکر نشان داد الگوریتم فورد-جانسون برای محدوده‌ای از مقادیر بهینه است. امروزه الگوریتمی ارائه شده‌است که به نتایج قوی‌تری نسبت به الگوریتم ماناکر دست یافته‌است.

منابع
-----

1. 1 2 3  Knuth, Donald (1997), "§5.2.3, Sorting by Selection", Sorting and Searching, The Art of Computer Programming, 3 (third ed.), Addison-Wesley, pp. 144–155, ISBN 978-0-201-89685-5
2. ↑  قدسی، محمد، داده ساختارها و مبانی الگوریتم‌ها، چاپ دوم، انتشارات فاطمی، ۱۳۸۹.
3. ↑  Cormen, Thomas H. ; Leiserson, Charles E. ; Rivest, Ronald L. ; Stein, Clifford (2009) [1990]. *Introduction to Algorithms* (3rd ed.). MIT Press and McGraw-Hill. ISBN 0-262-03384-4.
4. ↑  "هنر برنامه‌نویسی رایانه". *ویکی‌پدیا، دانشنامهٔ آزاد*. 2019-04-12.
5. ↑  «ScienceDirect». *www.sciencedirect.com*. دریافت‌شده در ۲۰۱۹-۰۴-۱۶.
6. ↑  «نتایج قوی‌تر از الگوریتم ماناکر».