Сортировка перемешиванием, или Шейкерная сортировка, или двунаправленная (англ. Cocktail sort) — разновидность пузырьковой сортировки. Анализируя метод пузырьковой сортировки, можно отметить два обстоятельства.
Во-первых, если при движении по части массива перестановки не происходят, то эта часть массива уже отсортирована и, следовательно, её можно исключить из рассмотрения.
Во-вторых, при движении от конца массива к началу минимальный элемент «всплывает» на первую позицию, а максимальный элемент сдвигается только на одну позицию вправо.
Эти две идеи приводят к следующим модификациям в методе пузырьковой сортировки. Границы рабочей части массива (то есть части массива, где происходит движение) устанавливаются в месте последнего обмена на каждой итерации. Массив просматривается поочередно справа налево и слева направо.
Лучший случай для этой сортировки — отсортированный массив ( ), худший — отсортированный в обратном порядке ( ).
Наименьшее число сравнений в алгоритме Шейкер-сортировки . Это соответствует единственному проходу по упорядоченному массиву (лучший случай)
Образно алгоритм можно описать так: на каждом шаге основного цикла рассматривается массив a[Left]÷a[Right], после выполнения двух внутренних циклов минимальный и максимальный элемент в исходном массиве перетекают к краям, минимальный в — a[Left], максимальный — в a[Right]. Пусть максимальный элемент имеет индекс k, тогда массив можно изобразить так: a[Left], a[1],..,a[k-1],A[k], a[k+1],..,a[Right];После сравнения A[k] с a[k+1] значение A[k] перейдет в k+1-ую ячейку, после сравнения k+1-й c k+2-й — в k+2-eю, и так далее, пока он не сместится в крайне правое положение с индексом Right. Аналогично для минимального. После выполнения цикла по всем подмассивам он отсортируется. Трассировка программы:
3 1 5 8 1 0 4 6 6 7 |
3 1 5 8 0 1 4 6 6 7 |
3 1 5 0 8 1 4 6 6 7 |
3 1 0 5 8 1 4 6 6 7 |
3 0 1 5 8 1 4 6 6 7 |
0 3 1 5 8 1 4 6 6 7 Left=1 |
0 1 3 5 8 1 4 6 6 7 |
0 1 3 5 1 8 4 6 6 7 |
0 1 3 5 1 4 8 6 6 7 |
0 1 3 5 1 4 6 8 6 7 |
0 1 3 5 1 4 6 6 8 7 |
0 1 3 5 1 4 6 6 7 8 Right=10 |
0 1 3 1 5 4 6 6 7 8 |
0 1 1 3 5 4 6 6 7 8 Left=3 |
0 1 1 3 4 5 6 6 7 8 |
#include <cstddef>
#include <utility>
template<typename T>
void shaker_sort(T array[], std::size_t size)
{
for (std::size_t left_idx = 0, right_idx = size - 1;
left_idx < right_idx;)
{
for (std::size_t idx = left_idx; idx < right_idx; idx++)
{
if (array[idx + 1] < array[idx])
{
std::swap(array[idx], array[idx + 1]);
}
}
right_idx--;
for (std::size_t idx = right_idx; idx > left_idx; idx--)
{
if (array[idx - 1] > array[idx])
{
std::swap(array[idx - 1], array[idx]);
}
}
left_idx++;
}
}
import std.stdio;
import std.algorithm.mutation: swapAt;
void shaker_sort(T)(ref T[] arr)
{
uint le = 0,
ri = arr.length - 1;
while (le <= ri)
{
foreach(k; le..ri)
if (arr[k] > arr[k+1])
arr.swapAt(k, k+1);
ri--;
foreach_reverse(k; le+1..ri+1)
if (arr[k-1] > arr[k])
arr.swapAt(k, k-1);
le++;
}
}
using System;
namespace SortLab
{
class Program
{
static void Main()
{
Sort();
}
/*Основная программа*/
static void Sort()
{
int[] myint = { 99, 88, 77, 66, 55, 44, 33, 22, 11, 8, 5, 3, 1 };
WriteArray(myint);
ShakerSort(myint);
WriteArray(myint);
Console.ReadLine();
}
/* Шейкер-сортировка */
static void ShakerSort(int[] myint)
{
int left = 0,
right = myint.Length - 1,
count = 0;
while (left < right)
{
for (int i = left; i < right; i++)
{
count++;
if (myint[i] > myint[i + 1])
Swap(myint, i, i + 1);
}
right--;
for (int i = right; i > left; i--)
{
count++;
if (myint[i - 1] > myint[i])
Swap(myint, i - 1, i);
}
left++;
}
Console.WriteLine("\nКоличество сравнений = {0}", count.ToString());
}
/* Поменять элементы местами */
static void Swap(int[] myint, int i, int j)
{
int glass = myint[i];
myint[i] = myint[j];
myint[j] = glass;
}
/*Вывести массив*/
static void WriteArray(int[] a)
{
foreach (int i in a)
Console.Write("{0}|", i.ToString());
Console.WriteLine("\n\n\n");
}
}
}
function shakerSort(array) {
// console.log('first array :', array);
let left = 0; //начало массива
let right = array.length - 1; //конец массива
let temp; //буфер
do {
for (let i = left; i < right; i++) {
if (array[i] > array[i + 1]) {
temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
}
}
// console.log('array :', array);
right--;
for (let i = right; left < i; i--) {
if (array[i] < array[i - 1]) {
temp = array[i];
array[i] = array[i - 1];
array[i - 1] = temp;
}
}
// console.log('array :', array);
left++;
} while (left < right);
// console.log('array :', array);
return array;
}
function cocktailSorting(&$a) {
$n = count($a);
$left = 0;
$right = $n - 1;
do {
for ($i = $left; $i < $right; $i++) {
if ($a[$i] > $a[$i + 1]) {
list($a[$i], $a[$i + 1]) = array($a[$i + 1], $a[$i]);
}
}
$right -= 1;
for ($i = $right; $i > $left; $i--) {
if ($a[$i] < $a[$i - 1]) {
list($a[$i], $a[$i - 1]) = array($a[$i - 1], $a[$i]);
}
}
$left += 1;
} while ($left <= $right);
}
1 public static void shakerSort(int array[]) {
2 int buff;
3 int left=0;
4 int right=array.length-1;
5 do {
6 for (int i=left; i<right;i++) {
7 if (array[i]>array[i+1]) {
8 buff = array[i];
9 array[i] = array[i + 1];
10 array[i + 1] = buff;
11 }
12 }
13 right--;
14 for (int i=right; i>left; i--) {
15 if (array[i]<array[i-1]) {
16 buff = array[i];
17 array[i] = array[i - 1];
18 array[i - 1] = buff;
19 }
20 }
21 left++;
22 } while (left <right);
23 }
1 sample = [0, -1, 5, -2, 3]
2
3 left = 0
4 right = len(sample) - 1
5
6 while left <= right:
7 for i in range(left, right, +1):
8 if sample[i] > sample[i + 1]:
9 sample[i], sample[i + 1] = sample[i + 1], sample[i]
10 right -= 1
11
12 for i in range(right, left, -1):
13 if sample[i - 1] > sample[i]:
14 sample[i], sample[i - 1] = sample[i - 1], sample[i]
15 left += 1
16
17 print(sample)
1 subroutine sort_cocktail(array_size,array)
2 integer i,j
3 integer last_unsorted, firs_unsorted, exchange
4 logical way
5 integer,intent(in) :: array_size
6 integer,intent(inout) :: array(array_size)
7 last_unsorted = array_size
8 firs_unsorted = 1
9 way = .true.
10 do j=1,array_size
11 if (way) then
12 do i=firs_unsorted,last_unsorted-1
13 if (array(i) .gt. array(i+1)) then
14 exchange = array(i)
15 array(i) = array(i+1)
16 array(i+1) = exchange
17 end if
18 end do
19 last_unsorted = last_unsorted -1
20 else
21 do i=last_unsorted-1,firs_unsorted,-1
22 if (array(i) .gt. array(i+1)) then
23 exchange = array(i)
24 array(i) = array(i+1)
25 array(i+1) = exchange
26 end if
27 end do
28 firs_unsorted = firs_unsorted +1
29 end if
30 way = .not. way
31 if(firs_unsorted .ge. last_unsorted) exit
32 end do
33 end subroutine
Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".
Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.
Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .