Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

Реализация сортировки в массиве стандартными методами

Массив элементов – это всегда особый класс, независимо от типа образующих его элементов, производный от базового класса Array.

Класс Array является основой для любого массива и предоставляет методы для создания, манипулирования (преобразования), поиска и сортировки на множестве элементов массива.

В частности, варианты метода Sort() обеспечивают реализацию механизмов сортировки элементов ОДНОМЕРНОГО массива объектов (в смысле представителей класса Object).

Сортировка элементов предполагает:

ПЕРЕБОР всего множества (или его части) элементов массива,

СРАВНЕНИЕ (значений) элементов массива в соответствии с определённым критерием сравнения. Критерии и алгоритмы сравнения могут задаваться либо с помощью массивов ключей, либо реализацией интерфейса IComparable.

Следующий вариант метода Sort сортирует полное множество элементов одноразмерного массива с использованием стандартного интерфейса сравнения.

public static void Sort(Array);

Стандартный интерфейс сравнения способен распознавать значения элементов массива и сравнивать эти элементы между собой.

Таким образом, никаких проблем не существует, если надо сравнить и переупорядочить массивы элементов базовых типов. Относительно …, System.Int16, System.Int32, System.Int64, …,System.Double,… всегда можно сказать, какой из сравниваемых элементов больше, а какой меньше.

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

При сортировке элементов массива ключей каждая из возможных перестановок элементов массива сопровождается перестановкой соответствующих item’ов массива. Таким образом, упорядочение массива целевых элементов осуществляется вне зависимости от реальных значений этих элементов данного массива. Читаются и сравниваются значения массива ключей, сами же элементы целевого массива перемещаются в соответствии с перемещениями элементов массива.

public static void Sort(Array, Array);

using System;

namespace SortArrays

{

class Class1

{

static void Main(string[] args)

{

int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив.

int[] keys = {10,1,2,3,4,5,6,7,8,9}; // Массив ключей.

for (i = 0; i < 10; i++) Console.WriteLine(“{0}: {1}”, i, iArr[i]);

// Сортировка массива с использованием ключей.

System.Array.Sort(keys,iArr);

Console.WriteLine(“=================================================”);

for (i = 0; i < 10; i++) Console.WriteLine(“{0}: {1}”, i, iArr[i]);

}

}

}

В процессе сортировки массива ключей элемент со значением ключа 10 перемещается в конец массива. При этом нулевой элемент целевого массива со значением 0 перемещается на последнюю позицию.

Целевой массив и массив ключей вида при сортировке

int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив.

int[] keys = {9,8,7,6,5,4,3,2,1,0}; // Массив ключей.

обеспечивают размещение элементов целевого массива в обратном порядке.

Следующее сочетание значений целевого массива и массива ключей обеспечивает изменение расположения первых четырёх элементов целевого массива:

int[] iArr = {0,1,2,3,4,5,6,7,8,9}; // Целевой массив.

int[] keys = {3,2,1,0}; // Массив ключей.

А такие наборы значений целевого и ключевого элементов массива при сортировке с использованием массива ключей обеспечивают изменение порядка целевых элементов массива с индексами 4, 5, 6, 7.

int[] iArr = {0,1,2,3,4,5,6,7,8,9};

int[] keys = {0,1,2,9,8,7,6,10,11,12};

Но самое главное и самое интересное в методе сортировки с использованием ключевого массива – это то, что в этом никаким образом не участвуют значения элементов целевого массива.

Надо отсортировать (изменить порядок расположения) составляющих массив массивов компонентов – надо всего лишь установить соответствие между элементами целевого массива и элементами массива ключей – и вызвать соответствующий вариант метода сортировки. Составляющие массива массивов будут восприняты как объекты-представители класса object и, не вдаваясь в подробности (а по какому принципу упорядочивать массивы?) будут переупорядочены в соответствии с новым порядком расположения элементов ключевого массива.

int[][] iArr = new int[3][]{

new int[]{0},

new int[]{0,1},

new int[]{0,1,2,3,4,5,6,7,8,9}

};

int[] keys = {3,2,1};

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

public static void Sort(Array,int,int);

Вариант метода сортировки основанный на сортировке элементов ключевого массива. Обеспечивает сортировку подмножества массива. Принципы выделения подмножества аналогичны рассмотренному выше варианту метода сортировки.

public static void Sort(Array,Array,int,int);

Сортировка на основе сравнения пар объектов-членов одномерного массива с использованием стандартного интерфейса сравнения

public static void Sort(Array,IComparer);

// Сортировка элементов с использованием стандартного Компарера.

// iArr – одномерный массив целочисленных значений.

// System.Collections.Comparer.DefaultInvariant стандартный Компарер.

try

{

System.Array.Sort(iArr,System.Collections.Comparer.DefaultInvariant);

}

catch (Exception ex)

{

Console.WriteLine(ex.ToString());

}

System.Collections.Comparer.DefaultInvariant - интерфейс определяет обобщённый метод сравнения значений (класса или типа), переопределение которого позволяет задать собственный специфический для данного класса метод сравнения элементов массива (interface implemented by each element of the Array).

using System;

using System.Collections;

namespace SortArrays

{

/// <summary>

/// Данные для массива элементов.

/// Подлежат сортировке в составе массива методом Sort.

/// Главная проблема заключается в том, что никто из тех, кто обеспечивает

/// встроенную сортировку, ни в классе Array, ни в классе Items не знает,

/// как воспринимать и каким образом сравнивать между собой

/// объекты-представители класса Items. Объекты itObj0 b itObj1

/// со значениями полей (7,5) и (5,7) - кто из них «больше»?

/// </summary>

class Items

{

/// <summary>

/// Конечно, можно об определении аксиом для установления отношения

/// порядка между элементами множества объектов-представителей класса

/// Items и о реализации соответствующих методов сравнения

/// можно было позаботиться при объявлении класса и просто не допускать

/// к стандартной сортировке объекты классов, в которых не определено

/// отношение порядка, однако в .NET используется другой подход.

/// <summary>

public int val1;

public int val2;

public Items (int key1, int key2)

{

val1 = key1;

val2 = key2;

}

}

/// <summary>

/// Предполагается, что отношение порядка над элементами

/// множества объектов-представителей соответствующего

/// класса может быть введено в любой момент. Для этого

/// достаточно иметь доступ к значениям соответствующих

/// полей объектов.

/// Для этого достаточно воспользоваться стандартными

/// библиотечными средствами .NET и реализовать (доопределить)

/// соответствующие интерфейсы (заготовки методов) сравнения.

/// Ниже объявляются два варианта процедур сравнения,

/// использование которых позволяет реализовать стандартные

/// алгоритмы сортировки, применяемые в классе Array.

/// ...КОМПАРАТОРЫ...

/// </summary>

class myComparer0: IComparer

{

int IComparer.Compare(object obj1, object obj2)

{

if (((Items)obj1).val1 == ((Items)obj2).val1) return 0;

if (((Items)obj1).val1 > ((Items)obj2).val1) return 1;

if (((Items)obj1).val1 < ((Items)obj2).val1) return -1;

else return 0;

}

}

class myComparer1: IComparer

{

int IComparer.Compare(object obj1, object obj2)

{

if (((Items)obj1).val2 == ((Items)obj2).val1) return 0;

if (((Items)obj1).val2 > ((Items)obj2).val2) return 1;

if (((Items)obj1).val2 < ((Items)obj2).val2) return -1;

else return 0;

}

}

/// <summary>

/// После реализации соответствующего интерфейса объекты-компараторы,

/// «профессиональные сравниватели», обеспечивают реализацию

/// стандартных алгоритмов сортировки.

/// </summary>

class Class1

{

[STAThread]

static void Main(string[] args)

{

// Объект-генератор «случайных» чисел.

// Стартует c использованием a time-dependent default seed value.

Random rnd = new Random();

int i;

// Массив Items.

Items[] itArr = new Items[10];

// Создали две версии Компареров, способных сравнивать пары

// объектов-представителей класса Items.

myComparer0 c0 = new myComparer0();

myComparer1 c1 = new myComparer1();

Console.WriteLine(“=================================================”);

// Проинициализировали массив объектов-представителей класса Items.

for (i = 0; i < 10; i++)

{

itArr[i] = new Items(rnd.Next(0,10),rnd.Next(0,10));

}

for (i = 0; i < 10; i++)

{

Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);

}

// Сортируются элементы массива типа Items.

// Условием успешной сортировки элементов массива является реализация

// интерфейса IComparer. Если Компарер не сумеет справиться с

// поставленной задачей - будет возбуждено исключение.

try

{

System.Array.Sort(itArr,c0);

}

catch (Exception ex)

{

Console.WriteLine(ex);

}

Console.WriteLine(“=================================================”);

for (i = 0; i < 10; i++)

{

Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);

}

Console.WriteLine(“=================================================”);

// Сортируются элементы массива типа Items.

// Условием успешной сортировки элементов массива является реализация

// интерфейса IComparer.

try

{

System.Array.Sort(itArr,c1);

}

catch (Exception ex)

{

Console.WriteLine(ex);

}

for (i = 0; i < 10; i++)

{

Console.WriteLine(“{0}: {1},{2}”, i, itArr[i].val1, itArr[i].val2);

}

}

}

}