Anwendung von Algorithmen im Spielbereich: Die Schnellsortierung wird in Unity3D verwendet, um Bestenlisten, Rucksäcke und andere Sammlungen zu sortieren und die Vor- und Nachteile zu analysieren

Artikelverzeichnis

Artikelverzeichnis

Vorwort

Relevante Information

1. Was ist Schnellsortierung?

Schnelle Sortierdefinition

Nachteile der schnellen Sortierung

2. Implementierung und Optimierung der Schnellsortierung

1. Grundlegender Schnellsortierungscode

2. Optimierter Sortieralgorithmus

Warum von IComparable erben?

So reduzieren Sie die Worst-Case-Szenarien der Schnellsortierung

Zusammenfassen


Hallo zusammen, ich bin Cairo Xiao8. Heute zeige ich Ihnen, wie Sie mithilfe der Schnellsortierung gängige Sammlungen in Spielen wie Rucksäcke und Ranglisten sortieren, sie mit anderen Algorithmen vergleichen und optimieren können.

Vorwort

Im Spielbereich ist es oft notwendig, die Sortierfunktion zu verwenden. Nachdem Spieler beispielsweise ihre Rucksäcke organisiert haben, können sie Requisiten nach Seltenheit, Erwerbsdatum, ID usw. sortieren, oder sie können die Gegenstände der Spieler sortieren. Punkte in der Bestenliste. Unterschiedliche Sortieralgorithmen haben unterschiedliche anwendbare Umgebungen. Einige Sortiervorgänge sind unter bestimmten Umständen schneller, unter anderen Umständen jedoch nicht so gut wie andere Sortieralgorithmen. Wir müssen also je nach Situation unterschiedliche Algorithmen auswählen.

In diesem Artikel werfen wir mithilfe von C#-Code einen Blick darauf, wie man die Schnellsortierung auf ein Spiel anwendet.


Relevante Information

Schnellsortieralgorithmus_bilibili_bilibili

Das zugrunde liegende Implementierungsprinzip von C# List<>.Sort() sorting_Das zugrunde liegende Prinzip von c#list-CSDN Blog

Schnelle Sortierung vs. Zusammenführungssortierung vs. Heap-Sortierung – Wer ist der stärkste Sortieralgorithmus? Warum Heap-Sortierung schnell ist – CSDN-Blog

4 Optimierungen von Quick Sort_Quick Sort Optimization-CSDN Blog

Werfen Sie einen Blick auf das zugrunde liegende Sortierprinzip der Methode Arrays.sort(), und es wurden seltsame Erkenntnisse hinzugefügt: Welche Sortierung wird am Ende von arraysort verwendet – CSDN-Blog

1. Was ist Schnellsortierung?

Schnelle Sortierdefinition

Die schnelle Sortierung ist ein häufig verwendeter Sortieralgorithmus mit einer zeitlichen Komplexität von O (nlog n) und einer räumlichen Komplexität von O (log n). Es handelt sich um einen instabilen Sortieralgorithmus. Bei der Verarbeitung großer Datenmengen ist die schnelle Sortierung am höchsten und daher am weitesten verbreitet.

Nachteile der schnellen Sortierung

Instabil:Schnellsortierung ist ein instabiler Sortieralgorithmus. Die Instabilität spiegelt sich darin wider, dass sich nach dem Sortieren die relativen Positionen von Elementen mit demselben Wert vor dem Sortieren ändern können. Für Beispiel: Wenn die Schüler einer Klasse beispielsweise nach ihren Noten sortiert werden, haben Xiao Ming und Xiao Hong die gleichen Ergebnisse. Vor dem Sortieren liegt Xiao Ming vor Xiao Hong, aber nach dem Sortieren steht Xiao Hong vor Xiao Ming.

Die Zeitkomplexität verringert sich unter bestimmten Umständen auf O(n^2):Wenn die zu sortierende Sammlung grundsätzlich in Ordnung ist, verringert sich die Zeitkomplexität der Schnellsortierung auf O( n^2) wird zur Auswahlsortierung.

2. Implementierung und Optimierung der Schnellsortierung

Nehmen wir als Beispiel die Sortierung der Schüler einer Klasse nach ihren Noten.

1. Grundlegender Schnellsortierungscode

public class Stu 
{
    public string Name;
    public int Score;

    public Stu(string name, int score)
    {
        Name = name;
        Score = score;
    }
}
class Program
{
    static void Main()
    {
        
        List<Stu> list = new List<Stu>() { 
            new Stu("小明", 100), new Stu("小红", 99), new Stu("小刚", 98),
            new Stu("小伟", 99), new Stu("小强", 100),
        };
        
        QuickSort(list, 0, list.Count - 1);
    }
    public static void QuickSort(List<Stu> list, int left, int right)
    {

        if (left >= right) return;

        Stu pivot = list[left];
        int i = left + 1, j = right;
        while (i < j)
        {
            while (i < j && list[i].Score >= pivot.Score) ++i;
            while (i < j && list[j].Score < pivot.Score) --j;
            if (i < j)
            {
                (list[i], list[j]) = (list[j], list[i]);
            }

        }
        if (list[i].Score < pivot.Score) --i;
        (list[i], list[left]) = (list[left], list[i]);
        QuickSort(list, left, i - 1);
        QuickSort(list, i + 1, right);
    }
}
Ergebnisse nach schneller Sortierung

 (list[i], list[j]) = (list[j], list[i]); um die Werte von i und j auszutauschen

Der obige Sortieralgorithmus sortiert die Ergebnisse jedes Schülers korrekt, aber die relative Position der beiden Schüler mit den gleichen Ergebnissen hat sich geändert.Vor dem Sortieren wird Xiao Ming eingestuft vor Xiaoqiang, aber nach der Sortierung steht Xiaoqiang vor Xiaoming. Manchmal ist das nicht das, was wir wollen

2. Optimierter Sortieralgorithmus

public class Stu : IComparable<Stu>
{
    public string Name;
    public int Score;
    int ID;

    public Stu(string name, int score, int id)
    {
        Name = name;
        Score = score;
        ID = id;
    }

    public int CompareTo(Stu other)
    {
        if (other.Score != Score) return other.Score - Score;
        return ID - other.ID;
    }
}
class Program
{
    static void Main()
    {
        List<Stu> list = new List<Stu>() { 
            new Stu("小明", 100, 1), new Stu("小红", 99, 2), new Stu("小刚", 98, 3),
            new Stu("小伟", 99, 4), new Stu("小强", 100, 5),
        };
        //list.Sort();因为Stu实现了IComparable接口,因此可以直接利用自带的排序方法
        QuickSort2(list, 0, list.Count - 1);

    }
    public static void QuickSort2(List<Stu> list, int left, int right)
    {

        if (left >= right) return;
        Stu pivot = list[left];
        int i = left + 1, j = right;
        while (i < j)
        {
            while (i < j && list[i].CompareTo(pivot) <= 0) ++i;
            while (i < j && list[j].CompareTo(pivot) > 0) --j;
            if (i < j)
            {
                (list[i], list[j]) = (list[j], list[i]);
            }

        }
        if (list[i].CompareTo(pivot) > 0) --i;
        (list[i], list[left]) = (list[left], list[i]);
        QuickSort2(list, left, i - 1);
        QuickSort2(list, i + 1, right);
    }
}

 Um sicherzustellen, dass die relative Reihenfolge nach dem Sortieren unverändert bleibt, habe ich eine neue Feld-ID hinzugefügt. Die ID wird nicht wiederholt. Die Sortierregel besteht darin, der Punktzahl Priorität einzuräumen und dann nach ID zu sortieren, mit der größeren ID an der unten.

Die allgemeine Sortieridee besteht darin, dass Elemente, die kleiner oder gleich Pivot sind, auf der linken Seite des Pivots platziert werden und Elemente, die größer als Pivot sind, auf der rechten Seite platziert werden. CompareTo wird verwendet, um die Größen zweier Elemente zu vergleichen.

Warum die IComparable-Schnittstelle erben?

Nachdem Sie diese Schnittstelle geerbt haben, können Sie die mit .net gelieferte Sortiermethode direkt zum Sortieren verwenden. Die mit .net gelieferte Methode hat die Sortierung weiter optimiert, ist effizienter und kann Ihnen die Zeit ersparen, den Sortiercode selbst zu schreiben .

Der Rückgabewert von CompareTo wird verwendet, um die Größe zu bestimmen. Wenn eine positive Zahl zurückgegeben wird, bedeutet dies, dass sie größer als das übergebene Objekt ist, und eine negative Zahl bedeutet, dass sie kleiner als das übergebene Objekt ist.

Optimierung der Sortierung durch .net:

  1. Wenn weniger Elemente sortiert werden müssen, verwenden Sie die Einfügungssortierung
  2. Introspektive Sortierung wird verwendet, wenn viele Elemente vorhanden sind. Das Prinzip ist schnelle Sortierung + Heap-Sortierung. Dieser Sortieralgorithmus beginnt zunächst mit schneller Sortierung. Wenn die Rekursionstiefe eine bestimmte Tiefe überschreitet (die Tiefe ist der Logarithmus der Anzahl der sortierten Elemente), es wechselt zur Heap-Sortierung.

So reduzieren Sie die Worst-Case-Szenarien der Schnellsortierung

Wenn das Array grundsätzlich geordnet ist, degeneriert die schnelle Sortierung in eine Auswahlsortierung, und die zeitliche Komplexität wird zu O (n ^ 2). Daher ist es sinnvoller, die Einfügungssortierung zu verwenden ist O(n)

Die Blasensortierung kann auch optimiert werden, um eine Komplexität von O(n) zu erreichen, wenn das Array grundsätzlich geordnet ist. Die Methode besteht darin, nach jeder Sortierung eine Beurteilung zu treffen. Wenn bei dieser Sortierung keine Elemente ausgetauscht werden, bedeutet dies, dass das Array In war Reihenfolge, beenden Sie die Sortierung direkt

Wenn Sie die Schnellwarteschlange verwenden müssen, können Sie von den folgenden zwei Aspekten ausgehen:

  1. Vermeiden Sie Array-Reihenfolge
  2. Wählen Sie zufällig Drehpunkte aus

Um das Sortieren des Arrays zu vermeiden, können Sie den Mischalgorithmus verwenden, um das Array vor dem Sortieren zu mischen und so das Worst-Case-Szenario zu reduzieren.

Zur Implementierung der zufälligen Auswahl von Drehpunkten beachten Sie bitte die entsprechenden Informationen oben im Artikel.

public static void Shuffle(int[] nums)
{
    Random rand = new Random();
    int n = nums.Length;
    for(int i=0;i<n; ++i)
    {
        int index=rand.Next(i, n);
        (nums[i], nums[index]) = (nums[index], nums[i]);
    }
}

Zusammenfassen

In diesem Artikel wird die Anwendung der Schnellsortierung im Spielbereich vorgestellt, die durch die instabilen Eigenschaften der Schnellsortierung verursachten Probleme aufgezeigt, Lösungen bereitgestellt und die Möglichkeit minimiert, dass die Schnellsortierung zu O(n^2) degeneriert.

おすすめ

転載: blog.csdn.net/m0_72922928/article/details/134466693