.NET には IList のインプレース ソート機能がありますか? 新しいコレクションを作成するのではなく、コレクション自体を並べ替える必要があります。
編集: 並べ替えを行う必要がある理由は、実際に何かが変更されていない限り、UI の再描画を避けるためです。1 つの項目だけが不適切な場合、100 の新しいカスタム コントロールを作成したくありません。
編集: 繰り返しますが、これは一般的な並べ替えだけでなく、その場での並べ替えに関する質問です。
.NET には IList のインプレース ソート機能がありますか? 新しいコレクションを作成するのではなく、コレクション自体を並べ替える必要があります。
編集: 並べ替えを行う必要がある理由は、実際に何かが変更されていない限り、UI の再描画を避けるためです。1 つの項目だけが不適切な場合、100 の新しいカスタム コントロールを作成したくありません。
編集: 繰り返しますが、これは一般的な並べ替えだけでなく、その場での並べ替えに関する質問です。
インプレースQuicksort / InsertionSort / ShellSort実装はどうですか:
public static class InPlaceQuickSort {
private static void Swap<T>(IList<T> set, int left, int right) {
T temp = set[left];
set[left] = set[right];
set[right] = temp;
}
private static Int32 Partition<T>(IList<T> set, int lBound, int rBound)
where T : IComparable<T> {
T pivot = set[rBound];
int left = lBound - 1;
int right = rBound;
while (true) {
while (set[++left].CompareTo(pivot) < 0) ;
while (set[--right].CompareTo(pivot) > 0) if (left == right) break;
if (left >= right) break;
Swap(set, left, right);
}
Swap(set, left, rBound);
return left;
}
private static IList<T> QuickSort<T>(IList<T> set, int lBound, int rBound)
where T : IComparable<T> {
if (lBound >= rBound) return set;
Int32 pivot = Partition(set, lBound, rBound);
QuickSort(set, lBound, pivot - 1);
QuickSort(set, pivot + 1, rBound);
return set;
}
public static IList<T> InsertionSort<T>(this IList<T> set)
where T : IComparable<T> {
for (Int32 index = 1; index < set.Count; index++) {
for (Int32 insertion = index; insertion > 0 && set[insertion - 1].CompareTo(set[insertion]) > 0; insertion--) {
Swap(set, insertion - 1, insertion);
}
}
return set;
}
public static IList<T> ShellSort<T>(this IList<T> set)
where T : IComparable<T> {
Int32 shell = 1;
while (shell < (set.Count / 3)) shell = shell * 3 + 1;
while (shell >= 1) {
for (Int32 index = shell; index < set.Count; index++) {
for (Int32 insertion = index; insertion >= shell && set[insertion - shell].CompareTo(set[insertion]) > 0; insertion -= shell) {
Swap(set, insertion - shell, insertion);
}
}
shell = shell / 3;
}
return set;
}
public static IList<T> QuickSort<T>(this IList<T> set)
where T : IComparable<T> {
return QuickSort<T>(set, 0, set.Count - 1);
}
}
そして、これを使用する方法は次のとおりです。
public static void Main() {
List<Int32> numbers = new List<int> { 1, 3, 2, 4, 2 };
foreach (Int32 number in numbers.QuickSort())
Console.WriteLine(number);
Console.ReadLine();
}
拡張メソッド ソリューションをシンプルに保ち、.NET の組み込みの並べ替えを使用する (カスタムIComparer
sも可能にする) 別の方法
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
var orderedList = list.OrderBy(i => i).ToArray();
for( int i = 0; i < list.Count; ++i )
{
list[i] = orderedList[i];
}
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer )
{
var orderedList = list.OrderBy(i => i, comparer).ToArray();
for (int i = 0; i < list.Count; ++i)
{
list[i] = orderedList[i];
}
}
}
class Program
{
static void Main(string[] args)
{
var orig = new List<int>() { 2, 3, 1 };
var toOrder = orig;
Console.Write("Orig: ");
orig.ForEach(i => Console.Write("{0} ", i));
toOrder.Sort();
Console.Write("\nOrdered: ");
toOrder.ForEach(i => Console.Write("{0} ", i));
Console.Write("\nOrig: ");
orig.ForEach(i => Console.Write("{0} ", i));
Console.ReadLine();
}
}
いいえ。IEnumerable.OrderBy()
またはSortedList<T>
を使用します。どちらも新しいコレクションを作成します。質問は、なぜ新しいコレクションを作成できないのですか?