Interested Article - Сортировка перемешиванием

Сортировка миксером , или Шейкерная сортировка, или двунаправленная ( англ. CockTail sort ) — разновидность пузырьковой сортировки . Анализируя метод пузырьковой сортировки, можно отметить два обстоятельства.

Во-первых , если при движении по части массива перестановки не происходят, то эта часть массива уже отсортирована и, следовательно, её можно исключить из рассмотрения.

Во-вторых , при движении от конца массива к началу минимальный элемент «всплывает» на первую позицию, а максимальный элемент сдвигается только на одну позицию вправо.

Эти две идеи приводят к следующим модификациям в методе пузырьковой сортировки. Границы рабочей части массива (то есть части массива, где происходит движение) устанавливаются в месте последнего обмена на каждой итерации. Массив просматривается поочередно справа налево и слева направо.

C++

#include <iostream>
#include <array>
#include <ctime>

using arr_int20 = std::array<int, 20>;

void filling(arr_int20& arr, arr_int20::value_type max_value) {
	for (arr_int20::value_type& item: arr)
		item = rand() % max_value;
}
void print(const arr_int20& arr) {
	for (const arr_int20::value_type& item : arr)
		std::cout << item << " ";
	std::cout << std::endl;
}

void shakerSort(arr_int20& arr) {
	int control = static_cast<int>(arr.size() - 1);
	int left = 0, right = control;
	do {
		for (int i = left; i < right; i++) {
			if (arr[i] > arr[i + 1]) {
				std::swap(arr[i], arr[i + 1]);
				control = i;
			}
		}
		right = control;
		for (int i = right; i > left; i--) {
			if (arr[i] < arr[i - 1]) {
				std::swap(arr[i], arr[i - 1]);
				control = i;
			}
		}
		left = control;
	} while (left < right);
}

int main() {
	arr_int20 arr;
	std::srand(static_cast<unsigned int>(std::time(nullptr)));

	filling(arr, 100);
	print(arr);

	shakerSort(arr);
	print(arr);

	return 0;
}

С#

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");
        }
    }
}

JavaScript

function shakerSort(array) {
    let left = 0; // начало массива
    let right = array.length - 1; // конец массива
    while (left < right) {
        for (let i = left; i < right; i++) {
            if (array[i] > array[i + 1]) {
                [array[i], array [i + 1]] = [array[i + 1], array [i]]
            }
        }
        right--;
        for (let i = right; left < i; i--) {
            if (array[i] < array[i - 1]) {
                [array[i], array [i - 1]] = [array[i - 1], array [i]]
            }
        }
        left++;
    }
    return array;
}

PHP

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--;
		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++;
	} while ($left <= $right);
}

ИЛИ

function FunctionCoocktailSort(&$array)
{
	$leftItem = 0;
	$rightItem = count($array) - 1;

	for ($i = $leftItem; $i < $rightItem; $i++) { 
		for ($j = $leftItem; $j < $rightItem; $j++) { 
			if ($array[$j] > $array[$j + 1]) {
				FunctionSwapVariables($array[$j], $array[$j + 1]);
			}
		}
		$rightItem--;
		for ($j = $rightItem; $j > $leftItem; $j--) { 
			if ($array[$j] < $array[$j - 1]) {
				FunctionSwapVariables($array[$j], $array[$j - 1]);
			}
		}
	}
}

Java

    public static void main(String[] args) {
        fillArray(arr);
        shakerSort(arr);
        System.out.println(Arrays.toString(arr));
       
    }

    private static void fillArray(int arr[]) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random() * 10 + 1);
        }
        System.out.println(Arrays.toString(arr));
    }

    public static void shakerSort(int arr[]) {
        int buff;
        int left = 0;
        int right = arr.length - 1;
        do {
            for (int i = left; i < right; i++) {
                if (arr[i] > arr[i + 1]) {
                    buff = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = buff;
                }
            }
            right--;
            for (int i = right; i > left; i--) {
                if (arr[i] < arr[i - 1]) {
                    buff = arr[i];
                    arr[i] = arr[i - 1];
                    arr[i - 1] = buff;
                }
            }
            left++;
        } while (left < right);
    }

Python

sample = [0, -1, 5, -2, 3]

left = 0
right = len(sample) - 1

while left <= right:
    for i in range(left, right, 1):
        if sample[i] > sample[i + 1]:
            sample[i], sample[i + 1] = sample[i + 1], sample[i]
    right -= 1

    for i in range(right, left, -1):
        if sample[i - 1] > sample[i]:
            sample[i], sample[i - 1] = sample[i - 1], sample[i]
    left += 1

print(sample)

T-SQL

create table #temp1
(
    id int primary key identity , -- ідентефикатор строки
    point int --значение
)

declare @left int = 0,
        @right int = (select count(*) from #temp1) - 1,
        @i int,
        @swap int

while @left <= @right
    begin
        set @i = @left
        while @i < @right + 1
            begin
                if (select point from #temp1 where id = @i) > (select point from #temp1 where id = @i + 1)
                    begin
                        set @swap = (select point from #temp1 where id = @i)

                        update #temp1
                        set point = (select point from #temp1 where id = @i + 1)
                        where id = @i

                        update #temp1
                        set point = @swap
                        where id = @i + 1
                    end
                set @i = @i + 1
            end

        set @right = @right - 1


        set @i = @right
        while @i > @left - 1
            begin
                if (select point from #temp1 where id = @i) < (select point from #temp1 where id = @i - 1)
                    begin
                        set @swap = (select point from #temp1 where id = @i)

                        update #temp1
                        set point = (select point from #temp1 where id = @i - 1)
                        where id = @i

                        update #temp1
                        set point = @swap
                        where id = @i - 1
                    end
                set @i = @i - 1
            end
        set @left = @left + 1


    end


select point
from #temp1

Fortran

subroutine sort_cocktail(array_size,array)
    integer i,j
    integer last_unsorted, firs_unsorted, exchange
    logical way
    integer,intent(in)      :: array_size
    integer,intent(inout)   :: array(array_size)
    last_unsorted = array_size
    firs_unsorted = 1
    way = .true.
    do j=1,array_size
        if (way) then
            do i=firs_unsorted,last_unsorted-1
                if (array(i) .gt. array(i+1)) then
                    exchange   = array(i)
                    array(i)   = array(i+1)
                    array(i+1) = exchange
                end if
            end do
            last_unsorted = last_unsorted -1
        else
            do i=last_unsorted-1,firs_unsorted,-1
                if (array(i) .gt. array(i+1)) then
                    exchange   = array(i)
                    array(i)   = array(i+1)
                    array(i+1) = exchange
                end if
            end do
            firs_unsorted = firs_unsorted +1
        end if
        way = .not. way
        if(firs_unsorted .ge. last_unsorted) exit
    end do
end subroutine

Ссылки

Источник —

Same as Сортировка перемешиванием