مرتبسازی حبابی دوسویه
الگوریتم مرتب سازی حبابی دو سویه یا الگوریتم مرتب سازی کوکتلی[۱] (cocktail shaker sort، shaker sort، ripple sort، shuttle sort، happy hour sort) یا شیکر سورت، یک نوع الگوریتم مرتبسازی حبابی است که الگوریتم مرتبسازی پایدار است و همچنین به صورت مقایسهای عمل مرتبسازی را انجام می دهد. این الگوریتم با الگوریتم مرتبسازی حبابی (buuble sort) که مرتبسازی در هر جهت لیست را مرتب میکند. پیادهسازی این الگوریتم مرتبسازی مشکلتر از الگوریتم مرتبسازی حبابی است.
محتویات |
شبه کد [ویرایش]
پیادهسازی سادهترین نوع مرتبسازی حبابی دوسویه بدین گونه است:
procedure bidirectionalbubbleSort( A : list of sortable items ) defined as: do swapped := false for each i in 0 to length( A ) - 2 do: if A[ i ]> A[ i + 1 ] then // test whether the two elements are in the wrong order swap( A[ i ], A[ i + 1 ] ) // let the two elements change places swapped := true end if end for if swapped = false then // we can exit the outer loop here if no swaps occurred. break do-while loop end if swapped := false for each i in length( A ) - 2 to 0 do: if A[ i ]> A[ i + 1 ] then swap( A[ i ], A[ i + 1 ] ) swapped := true end if end for while swapped // if no elements have been swapped, then the list is sorted end procedure
دراولین عبور از روی لیست به سمت راست بزرگترین عضو لیست به مکان صحیح خود منتقل میشود و در عبور بعدی از روی لیست به سمت چپ کوچکترین عنصر به جای اصلی خود در آغاز می رود. دومین عبور تکمیل کننده از روی لیست دومین عنصر بزرگ و دومین عنصر کوچک را به جای خود می برد و به همین ترتیب. بعد از گذشت i عبور از روی لیست i امین عنصر اول و i امین عنصر درون لیست در جای صحیح خود قرار دارند و نیازی به چک کردن ندارند. با کوچک کردن قسمتی از لیست که در قسمت مرتب میشود تعداد دستورات برای انجام الگوریتم نصف می شود.
procedure bidirectionalbubbleSort ( A : list of sortable items ) defined as: // `begin` and `end` marks the first and last index to check begin := -1 end := length( A ) - 2 do swapped := false // increases `begin` because the elements before `begin` are in correct order begin := begin + 1 for each i in begin to end do: if A[ i ]> A[ i + 1 ] then swap( A[ i ], A[ i + 1 ] ) swapped := true end if end for if swapped = false then break do-while loop end if swapped := false // decreases `end` because the elements after `end` are in correct order end := end - 1 for each i in end to begin do: if A[ i ]> A[ i + 1 ] then swap( A[ i ], A[ i + 1 ] ) swapped := true end if end for while swapped end procedure
تفاوتهای مرتب سازی حبابی دوسویه با مرتب سازی حبابی: تفاوت این دو در این است که به جای اینکه در هر مرحله از ته تا سر لیست را برویم، به طور به طور تناوبی از ته به سر و بعد از سر به ته لیست حرکت می کنیم. این الگوریتم کمی بهتر از مرتب سازی حبابی استاندارد عمل می کند. دلیل این هم این است که الگوریتم مرتب سازی حبابی فقط در طول لیست در یک جهت حرکت می کند بنابراین فقط می تواند عناصر در یک خانه در هر تکرار به جای اصلی خود نزدیک کند. به عنوان شاهد برای این قسمت می توان لیست زیر را در نظر گرفت (2، 3، 4، 5، 1) که با استفاده از الگوریتم مرتب سازی حبابی دوسویه یک مرحله اجرا دارد ولی انجام همین کار با استفاده از الگوریتم مرتب سازی حبابی 4 مرحله به طول می انجامد. نوعا زمان اجرای الگوریتم مرتب سازی حبابی نسبت به الگوریتم مربت سازی حبابی دوسویه کمتر از دو برابر است. یک بهینه سازی دیگر می توان انجام داد این است که می توان انجام داد این است که الگوریتم به نوعی مکان تقریبی آخرین جابه جایی انجام شده را به یاد سپارد. و در تکرار بعد دیگر خارج از این بازه انجام نمی شود و الگوریتم مسیر کوتاه تری دارد. از آنجا که مرتب سازی حبابی دوسویه در هر دو طرف حرکت می کند. محدودهٔ جابه جایی ممکن که برای جابه جایی نیاز است که شرط جابه جایی چک شود، در هر مرحله گذر کاهش می یابد که نتیجه کاهش یافتن کل زمان اجرای الگوریتم است.
تحلیل پیچیدگی الگوریتم [ویرایش]
مرتبهٔ پیچیدگی مرتب سازی حبابی دو سویه از (O(n2است. و این مرتبه پیچیدگی هم برای بدترین حالت و هم برای حالت میانگین است، ولی در بهترین حالت زمانی که لیست ورودی از قبل مرتب است مرتبه پیچیدگی از (O(n خواهد بود. به عنوان مثال اگر هر عنصر در حالت اولیه در نسبت به جای صحیح خود k خانه فاصله داشته باشد مرتبه پیچیدگی الگوریتم (O(k * n.
بهزبان جاوا [ویرایش]
class BidirBubbleSortAlgorithm extends SortAlgorithm { void sort(int a[]) throws Exception { int j; int limit = a.length; int st = -1; while (st <limit) { boolean flipped = false; st++; limit--; for (j = st; j <limit; j++) { if (stopRequested) { return; } if (a[j]> a[j + 1]) { int T = a[j]; a[j] = a[j + 1]; a[j + 1] = T; flipped = true; pause(st, limit); } } if (!flipped) { return; } for (j = limit; --j>= st;) { if (stopRequested) { return; } if (a[j]> a[j + 1]) { int T = a[j]; a[j] = a[j + 1]; a[j + 1] = T; flipped = true; pause(st, limit); } } if (!flipped) { return; } } pause(st, limit); } }
منابع [ویرایش]
- کتاب “The Art of Computer Programming”
- http://en.wikipedia.org/wiki/Cocktail_sort
- http://max.cs.kzoo.edu/~abrady/java/sorting/BidirBubbleSort.html