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

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