Einfügen in eine bereits sortierte Liste
Mit Java, habe ich eine Klasse, bekannt als Testklasse, die ein Element mit dem Namen Name, das ist ein string. Ich habe auch eine ArrayList von dieser Art, die bereits die alphabetisch nach Namen sortiert. Was ich tun möchte, ist zu finden die besten index, in dem Sie eine neue Instanz von Testklasse. Der beste Ansatz, den ich kommen könnte, so weit ist diese:
public static int findBestIndex(char entry, ArrayList<TestClass> list){
int desiredIndex = -1;
int oldPivot = list.size();
int pivot = list.size()/2;
do
{
char test = list.get(pivot).Name.charAt(0);
if (test == entry)
{
desiredIndex = pivot;
}
else if (Math.abs(oldPivot - pivot) <= 1)
{
if (test < entry)
{
desiredIndex = pivot + 1;
}
else
{
desiredIndex = pivot - 1;
}
}
else if (test < entry)
{
int tempPiv = pivot;
pivot = oldPivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
else
{
int tempPiv = pivot;
pivot = pivot - (oldPivot - pivot)/2;
oldPivot = tempPiv;
}
} while (desiredIndex < 0);
return desiredIndex;
}
Im wesentlichen, Brechen Sie die Reihe in der Hälfte, zu überprüfen, ob Ihr Wert geht vor, nach, oder in diesem Punkt. Wenn es nach prüfen der ersten Hälfte des Arrays. Andere weisen, überprüfen Sie die zweite Hälfte. Dann wiederholen. Ich verstehe, dass diese Methode nur tests, die von dem ersten Zeichen, aber das ist leicht behoben, und nicht relevant für mein Haupt-problem. Für einige Szenarien, dieser Ansatz funktioniert gut genug. Für die meisten, es funktioniert schrecklich. Ich gehe davon aus, dass es nicht die Suche nach einem neuen pivot-Punkt richtig, und wenn das der Fall ist, wie kann ich es beheben?
Edit: Zur Klarstellung, ich bin mit diesem für ein Inventar-system, so dass ich nicht sicher bin, ob eine LinkedList angemessen wäre. Ich bin mit einer ArrayList, weil Sie mehr sind mir vertraut, und so wäre es einfacher zu übersetzen in eine andere Sprache, falls erforderlich (was wahrscheinlich ist, im moment, vielleicht verschieben auf C#). Ich bin versucht zu vermeiden, Dinge wie Vergleichbares aus diesem Grund, als müsste ich komplett neu schreiben, wenn C# fehlt es.
Teil Bearbeiten Duex: herausfinden, was ich falsch machte. Anstelle der Verwendung des vorherigen drehpunkts, ich hätte die Einstellung und änderung der Grenzen des Bereichs, ich war die überprüfung und das erstellen der neuen pivot.
Collections.sort()
?Vielleicht bin ich nicht auf der Suche auf dieses Recht, aber wenn Sie feststellen, dass der Wert geht nachdem die ausgewählten (test) zeigen Sie, würden Sie nicht überprüfen Sie die zweite die Hälfte von dem array?
greifen nach jedem einfügen würde wahrscheinlich die langsamste Weg zu gehen, obwohl Geschwindigkeit ist nicht meine größte Sorge, da wird es wahrscheinlich nicht werden, viele Objekte verlagert-in und-out schnell.
das ist es, was ich versuche zu tun, aber wahrscheinlich mein Versuch dabei war völlig falsch, und das ist, wo ich bin mit dem problem.
es hängt davon ab, wie oft diese sortierte Liste zugegriffen wird. Wenn nicht, oft können Sie nur rekonstruieren, dass die Liste bei Bedarf.
InformationsquelleAutor user2423158 | 2013-05-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie bereits erwähnt, gibt es keinen Grund, dies umzusetzen, indem Sie sich selbst, einfaches code Beispiel:
(Basierend auf So finden Sie den index eines Elements in einem TreeSet?)
InformationsquelleAutor mrak
Sollten Sie so etwas wie eine PriorityQueue, das hat schon einen Sinn für Ordnung. Beim einfügen in eine collection mit einem Gefühl der Bestellung wird automatisch platzieren Sie das element an der richtigen Stelle mit minimalem Zeitaufwand(in der Regel log(n) oder weniger).
Wenn Sie wollen, um beliebige Einsätze, ohne diese, dann würde ich vorschlagen, mit einer LinkedList, die nicht in Anspruch genommen werden oder vollständig kopiert über einfügen ein einzelnes Element wie die ArrayList, die Sie derzeit haben. Während der Suche nach der richtigen Einfügeposition für eine LinkedList nehmen bis zu O(n) Zeit, in der Praxis wird es immer noch schneller, als mit einem log(n) bei der Suche nach dem richtigen Ort in einer ArrayList, aber dann müssen kopieren oder Sortieren Sie danach.
Auch der code für das finden der Einfügeposition in einer verknüpften Liste ist viel einfacher.
Gut, ich muss sagen, Ihr Grund für die nicht wollen, verwenden Sie eine LinkedList b/c es wäre leichter zu übersetzen, eine ArrayList zu C# ist nicht korrekt. Würden beide gleich leicht zu übersetzen ( ich würde sogar sagen, dass die LinkedList einfacher). Das wichtigste ist aber, Sie können nicht fügen Sie ein element in der Mitte eine ArrayList ohne Verschiebung aller Elemente nach. Dies umfasst das kopieren, die Teil der ArrayList, deutlich langsamer als eine LinkedList einfügen. Im Grunde, wenn Sie sind auf der Suche nach Effizienz, verwenden Sie die falschen datastructure.
InformationsquelleAutor greedybuddha
Gibt es andere Datenstrukturen verwendet werden könnten, verwenden anstelle von list wie ein Baum, Priorität usw.
InformationsquelleAutor Ayodeji
Ich denke, das problem ist in diesem bit der code:
Sind Sie, das die gleichen Aktionen, ob test < Eintrag, oder ob test - > Eintrag. Dies führt zu einer linearen Suche, wenn der Artikel den Sie suchen ist am Anfang des Arrays.
Ich benutze lieber (niedrig und hoch) wie
danke für den up Stimmen, ich vermute, der user wollte, dass seine Frage beantwortet und hatte kein Interesse, nach, dass
InformationsquelleAutor Bruce Martin
Es ist vielleicht nicht eine gute Idee, ein SortedSet (z.B. ein TreeSet) für diese, weil die Bäume nicht erlauben doppelte Elemente zu. Wenn Sie doppelte Elemente (z.B. TestClass Instanzen mit dem gleichen Namen), dann sollte eine Liste verwendet werden. So fügen Sie ein element in eine bereits sortierte Liste ist so einfach wie diese:
Dieser code erfordert Java 8 oder höher, kann aber umgeschrieben werden zu arbeiten in älteren Java-Versionen als gut.
InformationsquelleAutor Daniel Beer
Machen Sie eine Liste der Umsetzung Ihrer eigenen und in deiner add-Methode haben diese Zeilen:
InformationsquelleAutor hd1