Алгоритмы сортировки - C#
Формулировка задачи:
Используя сортировку слиянием, «быструю» сортировку, пирамидальную сортировку и сортировку подсчетами решить задачу:
Дана последовательность из n натуральных чисел. Расставить числа так, чтобы максимальная разность между двумя соседними числами была наименьшей
Решение задачи: «Алгоритмы сортировки»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private DateTime EventTime1, EventTime2;
private Thread t = new Thread(delegate() { });
private Random random = new Random();
private delegate void SetTextCallback(string text, SortingType sortingType);
private delegate void PerformStepCallback();
private enum SortingType { BubbleSort, SelectingSort, QuickSort, MergeSort };
public Form1()
{
InitializeComponent();
t.Abort();
}
private void b_ogl_1_Click(object sender, EventArgs e)
{
OpenFileDialog fd1 = new OpenFileDialog();
if (fd1.ShowDialog() != DialogResult.Cancel)
{
this.tb_see_1.Text = fd1.FileName;
}
}
private void b_ogl_2_Click(object sender, EventArgs e)
{
OpenFileDialog fd2 = new OpenFileDialog();
if (fd2.ShowDialog() != DialogResult.Cancel)
{
this.tb_see_2.Text = fd2.FileName;
}
}
/// <summary>
/// Swap two values
/// </summary>
/// <typeparam name="T">type of values</typeparam>
/// <param name="a">fisrt value</param>
/// <param name="b">second value</param>
private void Swap<T>(ref T a, ref T b)
{
T tmp = a; a = b; b = tmp;
}
private void PerformStep()
{
if (progressBar1.InvokeRequired)
{
PerformStepCallback p = new PerformStepCallback(PerformStep);
Invoke(p);
}
else progressBar1.PerformStep();
}
/// <summary>
/// Function to sort array by bubble method
/// </summary>
/// <typeparam name="T">type of sorted data</typeparam>
/// <param name="array">sorted array</param>
private void BubleSort<T>(T[] array)
where T : IComparable<T>
{
EventTime1 = DateTime.Now;
for (int i = 1; i < array.Length; i++)
{
for (int j = 0; j + 1 < array.Length; j++)
{
if (array[j].CompareTo(array[j + 1]) > 0)
{
Swap<T>(ref array[j], ref array[j + 1]);
}
}
PerformStep();
}
EventTime2 = DateTime.Now;
WrtiteTime(SortingType.BubbleSort);
WriteFile<T>(array);
MessageBox.Show("Sorting finnished successfuly.");
}
private void SelectingSort<T>(T[] array)
where T : IComparable<T>
{
EventTime1 = DateTime.Now;
for (int i = 0, k = array.Length - 1; i < k; ++i, --k)
{
int min = i,
max = i;
for (int j = i + 1; j < array.Length; ++j)
{
min = array[min].CompareTo(array[j]) > 0 ? j : min;
max = array[max].CompareTo(array[j]) < 0 ? j : max;
}
Swap<T>(ref array[i], ref array[min]);
Swap<T>(ref array[k], ref array[max]);
PerformStep();
}
EventTime2 = DateTime.Now;
WrtiteTime(SortingType.SelectingSort);
WriteFile<T>(array);
MessageBox.Show("Sorting finnished successfuly.");
}
/// <summary>
/// Function to sort array by quick sort method
/// </summary>
/// <typeparam name="T">type of sorted data</typeparam>
/// <param name="array">sorted array</param>
private void QuickSort<T>(T[] array)
where T : IComparable<T>
{
EventTime1 = DateTime.Now;
QuickSort<T>(array, 0, array.Length - 1);
EventTime2 = DateTime.Now;
WrtiteTime(SortingType.QuickSort);
WriteFile<T>(array);
MessageBox.Show("Sorting finnished successfuly.");
}
/// <summary>
/// Function to sort array by quick sort method
/// </summary>
/// <typeparam name="T">type of sorted data</typeparam>
/// <param name="array">sorted array</param>
/// <param name="left">begin of unsorted part</param>
/// <param name="right">end of unsorted part</param>
private void QuickSort<T>(T[] array, int left, int right)
where T : IComparable<T>
{
if (left < right)
{
T x = array[random.Next(left, right)];
int i = left, j = right;
while (i <= j)
{
while (array[i].CompareTo(x) < 0) ++i;
while (array[j].CompareTo(x) > 0) --j;
if (i <= j)
{
Swap(ref array[i], ref array[j]);
++i;
--j;
}
}
QuickSort<T>(array, left, j);
QuickSort<T>(array, i, right);
}
else
{
PerformStep();
}
}
/// <summary>
/// Sorting array using MergeSort method
/// </summary>
/// <typeparam name="T">type of array's elements.</typeparam>
/// <param name="array">sorting array.</param>
private void MergeSort<T>(T[] array)
where T : IComparable<T>
{
EventTime1 = DateTime.Now;
MergeSort<T>(array, new T[array.Length], 0, array.Length - 1);
EventTime2 = DateTime.Now;
WrtiteTime(SortingType.MergeSort);
WriteFile<T>(array);
MessageBox.Show("Sorting finnished successfuly.");
}
/// <summary>
/// Sorting array using MergeSort method.
/// </summary>
/// <typeparam name="T">type of array's elements.</typeparam>
/// <param name="array">sorting array.</param>
/// <param name="tmp">temporary array that used for sorting.
/// Size of sorted and temporary arrays must be the same.</param>
/// <param name="left">left index, from where sorting will be started.</param>
/// <param name="right">right index, where sorting will be finnished.</param>
private void MergeSort<T>(T[] array, T[] tmp, long left, long right)
where T : IComparable<T>
{
if (left >= right)
{
PerformStep();
return;
};
long mid = (left + right) / 2;
MergeSort<T>(array, tmp, left, mid);
MergeSort<T>(array, tmp, mid + 1, right);
Merge<T>(array, tmp, left, mid, right);
}
/// <summary>
/// Sorting array using MergeSort method.
/// </summary>
/// <typeparam name="T">type of array's elements.</typeparam>
/// <param name="array">sorting array.</param>
/// <param name="tmp">temporary array that used for sorting.
/// Size of sorted and temporary arrays must be the same.</param>
/// <param name="left">left index, from where sorting will be started.</param>
/// <param name="mid">middle of sorted array.</param>
/// <param name="right">right index, where sorting will be finnished.</param>
private void Merge<T>(T[] array, T[] tmp, long left, long mid, long right)
where T : IComparable<T>
{
long i = left,
j = mid + 1,
k = left;
while (i <= mid && j <= right)
{
if (array[i].CompareTo(array[j]) < 0)
{
tmp[k++] = array[i++];
}
else
{
tmp[k++] = array[j++];
}
}
while (i <= mid) tmp[k++] = array[i++];
while (j <= right) tmp[k++] = array[j++];
for (i = left; i <= right; ++i) array[i] = tmp[i];
}
/// <summary>
/// Write time of execution.
/// </summary>
/// /// <param name="sortingType"></param>
private void WrtiteTime(SortingType sortingType)
{
TimeSpan Eplased = EventTime2 - EventTime1;
string text = String.Format("{0:00}:{1:00}:{2:00},{3:000}",
Eplased.Hours,
Eplased.Minutes,
Eplased.Seconds,
Eplased.Milliseconds);
SetText(text, sortingType);
}
/// <summary>
/// Write text from another thread.
/// </summary>
/// <param name="text">text to write</param>
/// <param name="sortingType">type sort method</param>
private void SetText(string text, SortingType sortingType)
{
if (tb_time_bul.InvokeRequired)
{
SetTextCallback setText = new SetTextCallback(SetText);
Invoke(setText, new object[] { text, sortingType });
}
else
{
if (sortingType == SortingType.BubbleSort) tb_time_bul.Text = text;
if (sortingType == SortingType.SelectingSort) tb_time_vyb.Text = text;
if (sortingType == SortingType.QuickSort) tb_time_Q.Text = text;
if (sortingType == SortingType.MergeSort) textBoxMergeSortTime.Text = text;
progressBar1.Value = progressBar1.Maximum;
}
}
/// <summary>
/// Write data to file.
/// </summary>
/// <typeparam name="T">type of data</typeparam>
/// <param name="nmatr">file for writing</param>
private void WriteFile<T>(T[] nmatr)
{
string file = tb_see_2.Text;
try
{
TextWriter tw = new StreamWriter(file);
for (int i = 0; i < nmatr.Length; ++i)
tw.WriteLine(nmatr[i].ToString());
tw.Close();
}
catch (Exception exaption)
{
MessageBox.Show(exaption.Message, "Помилка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
/// <summary>
/// Read data from file.
/// </summary>
/// <param name="file">file for reading</param>
private int[] ReadFile(string file)
{
int[] nmatr = new int[] { };
try
{
TextReader tr = new StreamReader(file);
while ((file = tr.ReadLine()) != null)
{
file.Trim();
string[] matr = file.Split(' '.ToString().ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
nmatr = new int[matr.Length];
for (int i = 0; i < nmatr.Length; ++i)
nmatr[i] = Convert.ToInt32(matr[i]);
}
tr.Close();
}
catch (Exception exaption)
{
MessageBox.Show(exaption.Message, "Помилка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
return nmatr;
}
private void b_sort_bul_Click(object sender, EventArgs e)
{
string file = this.tb_see_1.Text;
int[] nmatr = ReadFile(file);
progressBar1.Value = 0;
t = new Thread(delegate() { BubleSort<int>(nmatr); });
progressBar1.Maximum = nmatr.Length;
t.Start();
}
private void b_sort_vyb_Click(object sender, EventArgs e)
{
string file = this.tb_see_1.Text;
int[] nmatr = ReadFile(file);
progressBar1.Value = 0;
t = new Thread(delegate() { SelectingSort<int>(nmatr); });
progressBar1.Maximum = nmatr.Length / 2;
t.Start();
}
private void b_sort_qsort_Click(object sender, EventArgs e)
{
string file = this.tb_see_1.Text;
int[] nmatr = ReadFile(file);
progressBar1.Value = 0;
t = new Thread(delegate() { QuickSort<int>(nmatr); });
progressBar1.Maximum = nmatr.Length;
t.Start();
}
private void buttonMergeSort_Click(object sender, EventArgs e)
{
string file = this.tb_see_1.Text;
int[] nmatr = ReadFile(file);
progressBar1.Value = 0;
t = new Thread(delegate() { MergeSort<int>(nmatr); });
progressBar1.Maximum = nmatr.Length;
t.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
buttonStop.PerformClick();
Application.Exit();
}
private void buttonStop_Click(object sender, EventArgs e)
{
t.Abort();
}
}
}