Матч 151, Сортировка слиянием (MergeSort)

Дивизион 2, Уровень 3

 

Рассмотрим сортировку методом слияния согласно следующему алгоритму:

 

Сортировка_Слиянием (массив а)

1. Если размер массива а £ 1, то вернуть а;

2. Разбить массив а на две части b и c:

2.1. Если массив а содержит 2*k чисел, то b содержит первые k чисел,  c – последние k чисел;

2.2. Если массив а содержит 2*k + 1 число, то b содержит первые k чисел,  c – последние k + 1 число;

3. sb = Сортировка_Слиянием (массив b);

4. sc = Сортировка_Слиянием (массив c);

5. return Слить(sb, sc);

 

Слить (массив b, массив c)

1. Создать пустой массив a;

2. Пока оба массива b и c не пустые, сравниваем первые элементы массивов b и c:

2.1. Если first(b) < first(c), то удалим первый элемент из b и добавим его в конец массива a;

2.2. Если first(b) > first(c), то  удалим первый элемент из c и добавим его в конец массива a;

2.3. Если first(b) = first(c), то удалим первые элементы из b и из c и добавим их в конец массива a;

3. Если массив b или c пустой, добавим весь непустой массив в конец массива a;

4. return a;

 

Класс: MergeSort

Метод: int howManyComparisons(vector<int> numbers)

Ограничения: numbers содержит от 0 до 50 элементов, -231 £ numbers[i] £ 231.

 

Вход. Массив чисел numbers.

 

Выход. Количество сравнений, необходимое совершить описанному выше алгоритму сортировки слиянием.

 

Пример входа

Numbers

{1, 2, 3, 4}

{2, 3, 2}

{-17}

 

Пример выхода

4

2

0

 

 

РЕШЕНИЕ

сортировка

 

Реализуем описанную сортировку слиянием и подсчитаем количество сравнений в переменной comps.

 

ПРОГРАММА

 

#include <cstdio>

#include <string>

#include <vector>

using namespace std;

 

class MergeSort

{

public:

  int howManyComparisons(vector<int> a)

  {

    return mergeSort(a);

  }

 

  int mergeSort(vector<int> &a)

  {

    if (a.size() <= 1) return 0;

    int k = a.size() / 2;

    vector<int> b = vector<int>(a.begin(), a.begin() + k);

    vector<int> c = vector<int>(a.begin() + k, a.end());

    int cb = mergeSort(b);

    int cc = mergeSort(c);

    return cb + cc + merge(a, b, c);

  }

 

  int merge(vector<int> &a, vector<int> &b, vector<int> &c)

  {

    unsigned ai = 0, bi = 0, ci = 0, comps = 0;

    while (bi != b.size() && ci != c.size() && ++comps)

    if (b[bi] == c[ci])

    {

      a[ai++] = b[bi++];

      a[ai++] = c[ci++];

    }

    else

    if (b[bi] < c[ci]) a[ai++] = b[bi++];

    else a[ai++] = c[ci++];

    while (bi != b.size()) a[ai++] = b[bi++];

    while (ci != c.size()) a[ai++] = c[ci++];

    return comps;

  }

};