1

現在、整数のリストがあります。このリストには、別のはるかに大きなリスト内の「アクティブな」オブジェクトを指すインデックス値が含まれています。「アクティブな」値の小さなリストが大きくなりすぎると、小さなリストを反復処理して非アクティブになった値を削除するループがトリガーされます。現在、非アクティブな値を無視して 2 番目のリストに追加するだけで、それらを削除します (2 番目のリストが再びいっぱいになると、同じプロセスが繰り返され、最初のリストに戻されます)。

このトリガーが発生した後、クイックソートの実装を使用してリストがソートされます。これはすべてうまくてダンディです。

- - - -質問 - - - - -

ただし、速度が向上する可能性があると思います。並べ替えが行われている間に非アクティブな値の削除を組み合わせることを想像しています。残念ながら、この方法でクイックソートを実装する方法が見つかりません。クイックソートがピボットで機能するという理由だけで、値がリストから削除された場合、ピボットは最終的にリスト内の存在しないスロットにアクセスしようとします。 .

では、2 つの操作を組み合わせる方法についてのアイデアはありますか? これを処理できるクイックソートほど高速なソートアルゴリズムを見つけることができないようです。または、おそらくそれをクイックソートに実装する方法がわかりません...ヒントをいただければ幸いです!

現在何が起こっているかをよりよく理解するためのコード: (現在の状況: 値は 0 から 200 万の範囲であり、同じ値は 2 つとなく、頻繁にソートされるため、一般的にほとんどソートされています)

if (deactive > 50000)//if the number of inactive coordinates is greater than 50k
{
    for (int i = 0; i < activeCoords1.Count; i++)
    {
         if (largeArray[activeCoords[i]].active == true)//if coordinate is active, readd to list
         {
             activeCoords2.Add(activeCoords1[i]);
         }
    }
    //clears the old list for future use
    activeCoords1.Clear();
    deactive = 0;
    //sorts the new list
    Quicksort(activeCoords2, 0, activeCoords2.Count() - 1);
 }    

    static void Quicksort(List<int> elements, int left, int right)
    {
        int i = left, j = right;
        int pivot = elements[(left + right) / 2];

        while (i <= j)
        {
            // p < pivot
            while (elements[i].CompareTo(pivot) < 0)
            {
                i++;
            }

            while (elements[j].CompareTo(pivot) > 0)
            {
                j--;
            }

            if (i <= j)
            {
                // Swap
                int tmp = elements[i];
                elements[i] = elements[j];
                elements[j] = tmp;

                i++;
                j--;
            }
        }

        // Recursive calls
        if (left < j)
        {
            Quicksort(elements, elements, left, j);
        }

        if (i < right)
        {
            Quicksort(elements, elements, i, right);
        }
    }
4

2 に答える 2

1

データ構造としてaList<T>または aを使用します。SortedDictionary<TKey, TValue>

ソートの理由(「感情に基づくマイクロ最適化」)は良いものではないので、私はそれを控えます. 正当な理由は、「パフォーマンスに測定可能な影響がある」ことです。

その場合 (または単にやりたい場合)、SortedDictionary をお勧めします。並べ替えはすべて完了しているため、一からやり直す必要はありません。

適切なデータ構造が 1 つあれば十分な場合は、2 つのリストを使いこなす必要はありません。red-black-tree が適切と思われ、これによるとSortedDictionary で使用されているようです

于 2013-05-04T16:31:55.403 に答える
1

赤黒木(または別のバランスの取れた二分木)を使用することでメリットが得られるように思えます。検索、挿入、および削除の時間は O(log n) になります。ツリーは常にソートされるため、再ソートに伴う大きなヒットが発生することはありません。

アクセスの種類 (検索、挿入、削除) の分割はどのようになっていますか? また、到達範囲の制約は何ですか?

于 2013-05-04T07:26:08.560 に答える