1

これはおそらく簡単な質問です。約 20 ~ 50 エントリの小さなリストがあるとします。何かのようなもの:

class Item
{
   int ItemNumber;
   int OrderNumber;
   string Name;
}

stored in something like
List<Item>

これは、OrderNumber が 1、2、3、4、....50 の汎用リストまたは配列に格納されます。簡単にするために、OrderNumber が既に別の場所で QuickSort によって List 内でソートされていると仮定しましょう (それによって事態が複雑になる場合を除きます)。

Item.OrderNumber = 30 を Item.OrderNumber = 20 などの場所に移動したいとしましょう。これを行うと、古い 20 が 21 になり、21 が 22 になり、30 になるまで、20 を超えるすべてのものをシフトする必要があります。また、Item.OrderNumber = 30 Item.OrderNumber = 34 に移動し、すべてを下に移動する必要があります。

リストを数回バブリングすることを考えていますが、これを行うためのより良い方法があることを願っています. リストのサイズは小さいですが、これはさまざまなことに対して多くのことを行う必要があります。

編集:お知らせするだけです。結果は最終的に、ある種のトランザクションでデータベースに保存する必要があります。

4

5 に答える 5

2

である必要がありList<T>ますか?そうでない場合は、SortedList<TKey, TValue>または の使用を検討してくださいSortedDictionary<TKey, TValue>。その後、OrderNumber をキーとして使用し、コレクションに任せることができます。

または、注文番号で比較する適切なものをList<T>使用できるため、次のようになります。List<T>.BinarySearchIComparer<T>

int position = list.BinarySearch(newOrder, orderComparer);
list.Insert(position >= 0 ? position : ~position, newOrder);

IComparer<T>ステートレスであるため、コード全体で同じインスタンスを使用できます。

編集: Robert Wagner's answerで提案されているように、このソリューションは他のエントリの OrderNumber を変更しません。

于 2009-01-20T06:21:56.197 に答える
1

私が正しく理解している場合、(何らかの理由で)OrderNumberをオブジェクト内に保持しようとしていますが、新しいオブジェクトをリストに追加し、他のすべてのオブジェクトにOrderNumberを調整させて新しいオブジェクトを適合させる必要があります。また、リスト内のアイテムの実際の順序は(必然的に)重要ではありません。

これは、リストをラップして独自の操作を実装することで実行できます(Move / Insert / Remove関数、これは次のことを行いました:

挿入 すべてのアイテムをループし、注文番号を1つ増やします。注文番号>=新しいアイテムの注文番号リストにアイテムを追加します

削除 アイテムの削除すべてのアイテムをループし、注文番号を1つ減らします。注文番号>削除されたアイテムの注文番号

移動 アイテムの削除アイテムの番号の付け直しアイテムの挿入

于 2009-01-20T07:24:09.627 に答える
0

リストにデータを入力した後で並べ替えて、最後に貼り付けてデータを入力します。常にソートする必要がある場合は、Skeetの言うことを実行してください。

于 2009-01-20T06:58:59.757 に答える
0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Class1
{                     
    static void Main()
    {
        var beatles = new LinkedList<string>();

        beatles.AddFirst("John");                        
        LinkedListNode<string> nextBeatles = beatles.AddAfter(beatles.First, "Paul");
        nextBeatles = beatles.AddAfter(nextBeatles, "George");
        beatles.AddAfter(nextBeatles, "Ringo");


        LinkedListNode<string> paulsNode = beatles.NodeAt(1); // middle's index
        LinkedListNode<string> recentHindrance = beatles.AddBefore(paulsNode, "Yoko");
        recentHindrance = beatles.AddBefore(recentHindrance, "Aunt Mimi");
        beatles.AddBefore(recentHindrance, "Father Jim");


        Console.WriteLine("{0}", string.Join("\n", beatles.ToArray()));

        Console.ReadLine();                       
    }
}

public static class Helper
{
    public static LinkedListNode<T> NodeAt<T>(this LinkedList<T> l, int index)
    {
        LinkedListNode<T> x = l.First;

        while ((index--) > 0) x = x.Next;

        return x;
    }
}
于 2009-01-20T05:49:57.073 に答える
0

二重連結リストを使用する場合、OrderNumber = 30 を 19 の後または 20 の前の位置に非常に安価に挿入できます。次に、30 未満の OrderNumber まで繰り返し、各注文を 1 ずつ増やします。リストの項目を上に移動します。

于 2009-01-20T05:52:04.277 に答える