Files
InternalSortMethods/InternalSortMethods/Models/SortingAlgorithms.cs
2026-04-12 19:40:01 +03:00

277 lines
6.7 KiB
C#

using System.Collections.Generic;
namespace InternalSortMethods.Models;
public abstract class SortingAlgorithm
{
public abstract string Name { get; }
public abstract string NameRu { get; }
protected List<SortStep> Steps { get; } = [];
protected int[] _array = [];
public SortingResult Sort(int[] array)
{
_array = (int[])array.Clone();
Steps.Clear();
OnSort();
return new SortingResult
{
SortedArray = _array,
Steps = [.. Steps]
};
}
protected void Compare(int i, int j)
{
Steps.Add(new SortStep(i, j, SortActionType.Compare));
}
protected void Swap(int i, int j)
{
(_array[i], _array[j]) = (_array[j], _array[i]);
Steps.Add(new SortStep(i, j, SortActionType.Swap, (int[])_array.Clone()));
}
protected void SetValue(int index, int value)
{
_array[index] = value;
Steps.Add(new SortStep(index, -1, SortActionType.Set, (int[])_array.Clone()));
}
protected void MarkSorted(int index)
{
Steps.Add(new SortStep(index, -1, SortActionType.MarkSorted));
}
protected void MarkPivot(int index)
{
Steps.Add(new SortStep(index, -1, SortActionType.MarkPivot));
}
protected abstract void OnSort();
}
public class BubbleSort : SortingAlgorithm
{
public override string Name => "Bubble Sort";
public override string NameRu => "Пузырьковая";
protected override void OnSort()
{
int n = _array.Length;
for (int i = 0; i < n - 1; i++)
{
bool swapped = false;
for (int j = 0; j < n - i - 1; j++)
{
Compare(j, j + 1);
if (_array[j] > _array[j + 1])
{
Swap(j, j + 1);
swapped = true;
}
}
MarkSorted(n - i - 1);
if (!swapped) break;
}
MarkSorted(0);
}
}
public class SelectionSort : SortingAlgorithm
{
public override string Name => "Selection Sort";
public override string NameRu => "Выбором";
protected override void OnSort()
{
int n = _array.Length;
for (int i = 0; i < n - 1; i++)
{
int minIdx = i;
for (int j = i + 1; j < n; j++)
{
Compare(j, minIdx);
if (_array[j] < _array[minIdx])
minIdx = j;
}
if (minIdx != i)
Swap(i, minIdx);
MarkSorted(i);
}
MarkSorted(n - 1);
}
}
public class InsertionSort : SortingAlgorithm
{
public override string Name => "Insertion Sort";
public override string NameRu => "Вставками";
protected override void OnSort()
{
int n = _array.Length;
for (int i = 1; i < n; i++)
{
int key = _array[i];
int j = i - 1;
Compare(j, i);
while (j >= 0 && _array[j] > key)
{
SetValue(j + 1, _array[j]);
j--;
if (j >= 0) Compare(j, i);
}
SetValue(j + 1, key);
}
MarkSorted(0);
}
}
public class QuickSort : SortingAlgorithm
{
public override string Name => "Quick Sort";
public override string NameRu => "Быстрая";
protected override void OnSort()
{
QuickSortRecursive(0, _array.Length - 1);
MarkSorted(0);
}
private void QuickSortRecursive(int low, int high)
{
if (low < high)
{
int pi = Partition(low, high);
QuickSortRecursive(low, pi - 1);
QuickSortRecursive(pi + 1, high);
}
}
private int Partition(int low, int high)
{
int pivot = _array[high];
MarkPivot(high);
int i = low - 1;
for (int j = low; j < high; j++)
{
Compare(j, high);
if (_array[j] < pivot)
{
i++;
if (i != j) Swap(i, j);
}
}
if (i + 1 != high) Swap(i + 1, high);
MarkSorted(i + 1);
return i + 1;
}
}
public class MergeSort : SortingAlgorithm
{
public override string Name => "Merge Sort";
public override string NameRu => "Слиянием";
protected override void OnSort()
{
MergeSortRecursive(0, _array.Length - 1);
MarkSorted(0);
}
private void MergeSortRecursive(int left, int right)
{
if (left < right)
{
int mid = left + (right - left) / 2;
MergeSortRecursive(left, mid);
MergeSortRecursive(mid + 1, right);
Merge(left, mid, right);
}
}
private void Merge(int left, int mid, int right)
{
int n1 = mid - left + 1;
int n2 = right - mid;
int[] leftArr = new int[n1];
int[] rightArr = new int[n2];
for (int x = 0; x < n1; x++) leftArr[x] = _array[left + x];
for (int x = 0; x < n2; x++) rightArr[x] = _array[mid + 1 + x];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2)
{
Compare(left + i, mid + 1 + j);
if (leftArr[i] <= rightArr[j])
{
SetValue(k, leftArr[i]);
i++;
}
else
{
SetValue(k, rightArr[j]);
j++;
}
k++;
}
while (i < n1)
{
SetValue(k, leftArr[i]);
i++; k++;
}
while (j < n2)
{
SetValue(k, rightArr[j]);
j++; k++;
}
}
}
public class HeapSort : SortingAlgorithm
{
public override string Name => "Heap Sort";
public override string NameRu => "Кучей";
protected override void OnSort()
{
int n = _array.Length;
for (int i = n / 2 - 1; i >= 0; i--)
Heapify(n, i);
for (int i = n - 1; i > 0; i--)
{
Swap(0, i);
MarkSorted(i);
Heapify(i, 0);
}
MarkSorted(0);
}
private void Heapify(int heapSize, int root)
{
int largest = root;
int left = 2 * root + 1;
int right = 2 * root + 2;
if (left < heapSize)
{
Compare(left, largest);
if (_array[left] > _array[largest])
largest = left;
}
if (right < heapSize)
{
Compare(right, largest);
if (_array[right] > _array[largest])
largest = right;
}
if (largest != root)
{
Swap(root, largest);
Heapify(heapSize, largest);
}
}
}