Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсовая работа по алгоритмам.docx
Скачиваний:
28
Добавлен:
14.09.2019
Размер:
113 Кб
Скачать
☆

3.4 Анализ пирамидальной сортировки

Сначала оценим время выполнения процедуры pushdown. Из листинга видно, что тело цикла while (т.е. отдельная итерация этого цикла) выполняется за фиксированное время. После каждой итерации переменная г по крайней мере вдвое увеличивает свое значение. Поэтому, учитывая, что начальное значение г равно first, после i итераций будем иметь г > first * 2'. Цикл while выполняется до тех пор, пока г > last/2. Это условие будет выполняться, если выполняется неравенство first * 2' > last/2. Последнее неравенство можно переписать как i > log(last/first) - 1.

Следовательно, число итераций цикл while в процедуре pushdown не превышает log(last/first). Поскольку first > 1 и last < n, то из (8.8) следует, что на каждый вызов процедуры pushdown в строках (2) и (5) затрачивалось время, по порядку небольшое, чем O(logn). Очевидно, что цикл for строк (1), (2) выполняется n/2 раз. Поэтому общее время выполнения этого цикла имеет порядок O(n logn). Цикл в строках (3) - (б) выполняется n - 1 раз. Следовательно, на выполнение всех перестановок в строке (4) тратится время порядка О(n), а на восстановление частично упорядоченного дерева (строка (5)) — О(n logn). Отсюда вытекает, что общее время выполнения цикла в строках (3) - (б) имеет порядок О(n logn) и такой же порядок времени выполнения всей процедуры heapsort. Несмотря на то что процедура heapsort имеет время выполнения порядка О(n logn) в самом худшем случае, в среднем ее время несколько хуже, чем в быстрой сортировке, хотя и имеет тот же порядок. Пирамидальная сортировка интересна в теоретическом плане, поскольку это первый рассмотренный нами алгоритм, имеющий в самом худшем случае время выполнения О(n logn). В практических ситуациях этот алгоритм полезен тогда, когда надо не сортировать все n элементов списка, а только отобрать k наименьших элементов, и при этом k значительно меньше п. В последнем примечании указывалось, что в действительности время выполнения цикла в строках (1), (2) имеет порядок О(n). Если надо сделать только k итераций цикла (3) - (5), то на это потратится время порядка O(k logn). Поэтому отбор k минимальных элементов процедура heapsort выполнит за время порядка О(n + k logn). Отсюда следует, что при k < n/logn на выполнение этой операции потребуется время порядка О(n)

3.5 Смотреть приложение b «Пирамидальная сортировка»

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleApplication1

{

class PyramidSorting

{

//добавление элемента к пирамиде

static int add2pyramid(double[] arr, int i, int N)

{

int imax;

double buf;

if ((2 * i + 2) < N)

{

if (arr[2 * i + 1] < arr[2 * i + 2]) imax = 2 * i + 2;

else imax = 2 * i + 1;

}

else imax = 2 * i + 1;

if (imax >= N) return i;

if (arr[i] < arr[imax])

{

buf = arr[i];

arr[i] = arr[imax];

arr[imax] = buf;

if (imax < N / 2) i = imax;

}

return i;

}

public static void sorting(double[] arr, int len)

{

//шаг 1: постройка пирамиды

for (int i = len / 2 - 1; i >= 0; --i)

{

long prev_i = i;

i = add2pyramid(arr, i, len);

if (prev_i != i) ++i;

}

Console.WriteLine();

Console.WriteLine("\nПросеивание:");

for (int s = 0; s < len; s++) Console.Write(" " + arr[s]);

//шаг 2: сортировка

double buf;

for (int k = len - 1; k > 0; --k)

{

buf = arr[0];

arr[0] = arr[k];

arr[k] = buf;

int i = 0, prev_i = -1;

while (i != prev_i)

{

prev_i = i;

Console.WriteLine();

Console.WriteLine("\nПерестановка:");

for (int s = 0; s < len; s++) Console.Write(" " + arr[s]);

i = add2pyramid(arr, i, k);

}

if (k > 1)

{

Console.WriteLine();

Console.WriteLine("\nПросеивание:");

for (int s = 0; s < len; s++) Console.Write(" " + arr[s]);

}

}

}

static void Main(string[] args)

{

double M = 0;

double[] arr = new double[24];

//заполнение массива случайными числами

Random rd = new Random();

for (int i = 0; i < arr.Length; ++i)

{

arr[i] = rd.Next(1, 50);

}

Console.WriteLine("Множество перед сортировкой:");

foreach (double x in arr) Console.Write(x + " ");

PyramidSorting.sorting(arr, arr.Length);

Console.WriteLine("\n\nМножество после сортировки сортировкой:");

foreach (double x in arr) Console.Write(x + " ");

for (int i = 0; i < arr.Length; ++i) M = 24 * Math.Log(24);

Console.WriteLine("\n\nЭффективность сортировки:" + M);

Console.WriteLine("\n\nнажмите <Enter> для выхода");

Console.ReadLine();

}

}

}

Рис 9