支持泛型的 C# 2.0 内部排序算法大全
本人原创,注释均为英文,见谅:
/*
* Common internal sorting algorithms.
*
* Implemented in C# v2.0 with generic support.
*
*
* Author: Cai Min
* Nick Name: Itecgo / 谁说眼泪是醉
*
* QQ: 28592801
* Email: caiwen@mail.ustc.edu.cn
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace CaiMin.ComputerScience
{
/// <summary>
/// The interface for sorting algorithms.
/// </summary>
interface ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
void Sort(T[] items);
}
public class Sort<T>
{
/// <summary>
/// Swaps the specified two items.
/// </summary>
/// <param name="items"></param>
/// <param name="left"></param>
/// <param name="right"></param>
public static void Swap(T[] items, int left, int right)
{
T temp = items[right];
items[right] = items[left];
items[left] = temp;
}
}
/// <summary>
/// The bubble sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
public class BubbleSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
for (int i = (items.Length - 1); i >= 0; i--)
{
for (int j = 1; j <= i; j++)
{
if (items[j - 1].CompareTo(items[j]) > 0)
Sort<T>.Swap(items, j - 1, j);
}
}
}
}
/// <summary>
/// The insertion sort algorithm.
/// </summary>
public class InsertionSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
for (int i = 1; i < items.Length; i++)
{
T key = items[i];
// Insert items[j] into the sorted sequence items[1..j-1].
int j = i;
while (j > 0 && (items[j - 1].CompareTo(key) > 0))
{
items[j] = items[j - 1];
j--;
}
items[j] = key;
}
}
}
/// <summary>
/// The selection sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
public class SelectionSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
for (int i = 0; i < items.Length - 1; i++)
{
int min = i;
for (int j = i + 1; j < items.Length; j++)
if (items[j].CompareTo(items[min]) < 0)
min = j;
Sort<T>.Swap(items, i, min);
}
}
}
/// <summary>
/// The quick sort algorithm.
/// </summary>
public class QuickSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
this.Sort(items, 0, items.Length - 1);
}
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
/// <param name="p"></param>
/// <param name="r"></param>
public void Sort(T[] items, int p, int r)
{
if (p < r)
{
int q = this.Partition(items, p, r);
this.Sort(items, p, q - 1);
this.Sort(items, q + 1, r);
}
}
/// <summary>
/// Partitions the specified items.
/// </summary>
/// <param name="items"></param>
/// <param name="p"></param>
/// <param name="r"></param>
/// <returns></returns>
private int Partition(T[] items, int p, int r)
{
T x = items[r];
int i = p - 1;
for (int j = p; j < r; j++)
if (items[j].CompareTo(x) <= 0)
Sort<T>.Swap(items, i++, j);
Sort<T>.Swap(items, i + 1, r);
return i + 1;
}
}
/// <summary>
/// The Shell sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
public class ShellSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
int increment = 3;
while (increment > 0)
{
for (int i = 0; i < items.Length; i++)
{
int j = i;
T temp = items[i];
while ((j >= increment) && (items[j - increment].CompareTo(temp) > 0))
{
items[j] = items[j - increment];
j -= increment;
}
items[j] = temp;
}
if (increment / 2 != 0)
increment /= 2;
else if (increment == 1)
increment = 0;
else
increment = 1;
}
}
}
/// <summary>
/// The merge sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
public class MergeSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
T[] temp = new T[items.Length];
this.Sort(items, temp, 0, items.Length - 1);
}
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
private void Sort(T[] items, T[] tempItems, int left, int right)
{
if (right > left)
{
int mid = (right + left) / 2;
this.Sort(items, tempItems, left, mid);
this.Sort(items, tempItems, mid + 1, right);
this.Merge(items, tempItems, left, mid + 1, right);
}
}
/// <summary>
/// Merges the specified items.
/// </summary>
/// <param name="items"></param>
private void Merge(T[] items, T[] tempItems, int left, int mid, int right)
{
int left_end = mid - 1;
int tmp_pos = left;
int num_elements = right - left + 1;
while ((left <= left_end) && (mid <= right))
{
if (items[left].CompareTo(items[mid]) <= 0)
{
tempItems[tmp_pos] = items[left];
tmp_pos++;
left++;
}
else
{
tempItems[tmp_pos] = items[mid];
tmp_pos++;
mid++;
}
}
while (left <= left_end)
{
tempItems[tmp_pos] = items[left];
left++;
tmp_pos++;
}
while (mid <= right)
{
tempItems[tmp_pos] = items[mid];
mid++;
tmp_pos++;
}
for (int i = 0; i <= num_elements; i++)
{
items[right] = tempItems[right];
right--;
}
}
}
/// <summary>
/// The heap sort algorithm.
/// </summary>
/// <typeparam name="T"></typeparam>
public class HeapSort<T> : ISort<T> where T : IComparable<T>
{
/// <summary>
/// Sorts the specified items.
/// </summary>
/// <param name="items"></param>
public void Sort(T[] items)
{
for (int i = (items.Length / 2) - 1; i >= 0; i--)
SiftDown(items, i, items.Length);
for (int i = items.Length - 1; i >= 1; i--)
{
Sort<T>.Swap(items, 0, i);
this.SiftDown(items, 0, i - 1);
}
}
/// <summary>
/// Sifts down the specified items.
/// </summary>
/// <param name="items"></param>
private void SiftDown(T[] items, int root, int bottom)
{
int maxChild;
bool done = false;
while ((root * 2 <= bottom) && (!done))
{
if (root * 2 == bottom)
maxChild = root * 2;
else if (items[root * 2].CompareTo(items[root * 2 + 1]) > 0)
maxChild = root * 2;
else
maxChild = root * 2 + 1;
if (items[root].CompareTo(items[maxChild]) < 0)
{
Sort<T>.Swap(items, root, maxChild);
root = maxChild;
}
else
done = true;
}
}
}
}