zwei Listen aneinanderhängen
Übersicht

![]() |
UNZBetreff: zwei Listen aneinanderhängen |
![]() Antworten mit Zitat ![]() |
---|---|---|
Moin Moin,
wie der Titel schon sagt, möchte ich zwei TLists aneinanderhängen, dass heißt aus zwei Listen soll eine werden. Ich hatte gedacht, dafür gibts was vordefiniertes, aber ich finde im codearchiv/forum nichts und google konnte mir auch nicht helfen. Man muss doch nur den letzen Link der ersten Liste auf das erste Element in der zweiten Liste zeigen lassen, um sie zu verketten, oder? Aber wie macht man das? |
||
Das muss besser als perfekt! |
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich würde dem zu gerne nachgehen, aber ich habe mein BlitzMax nicht mit im Urlaub. Du scheinst dich aber eh damit auszukennen - und das Folgende gilt jetzt auch für die Sache mit TextAreaText: wenn man einen Blick in den Quelltext der Module wagt, lohnt sich das oft (->Lerneffekt, weil man selber draufgekommen ist). Kann natürlich sein, dass man in den Sources nix findet, also auch nicht verzweifeln ![]() Hatte jetzt nur die BlitzMax-Hilfe zur Verfügung und hab auch nicht lang geschaut, aber wenn du was schnelles, dreckiges brauchen kannst: Code: [AUSKLAPPEN] list = TList.FromArray(list.ToArray() + list2.ToArray())
|
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das, in array umwandeln und zurück umwandeln, hätte ich auch vorgeschlagen.
Leider war mir das ZU dreckig ![]() Die simpelste form wäre doch immernoch: BlitzMax: [AUSKLAPPEN] Local list1:TList = CreateList () hat so ziemlich den selben effekt. Nun vermutungen: Es kann sein, das die TList den ersten und / oder letzten link hält. Ausserdem haben TLinks _value etc, als felder. da müsste auch eine art _prev _succ oder sonstwas bei sein. Keine ahnung genau, aber irgendwas in der art existiert, und eines davon musst du ändern ![]() Spiel einfach rum, wird schon hinhaun ![]() (und natürlich Liste.firstLink() und liste.LastLink() nicht vergessen!) |
||
![]() |
Tennisball |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
Hab's mal ausprobiert. BlitzMax: [AUSKLAPPEN] SuperStrict Funktioniert tatsächlich. Gruß, Tennisball |
||
![]() |
Nova |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kein Quellcode, nur eine Idee (vielleicht geht das gar nicht)
Ich würde ja versuchen, beim letzten Element der ersten Liste die "nächster"-Variable auf das erste Element der zweiten Liste zu setzen (und umgekehrt). Wäre eine schöne Sache, falls es funktioniert. ![]() |
||
AMD Athlon II 4x3,1GHz, 8GB Ram DDR3, ATI Radeon HD 6870, Win 7 64bit |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Tennisball, nova, ihr habt recht.
Es funktioniert, wenn man liste1 letzter link auf liste2 erster link pointert, und umgekehrt. ABER: Das setzt die grundlegenden listenfunktionen ausser gefecht. Nach ein wenig stöbern ist mir dann aufgefallen, das tlist ein "._head" hat. Dies ist ein leerer link, welcher mit _succ auf den ersten link zeigt sowiet mit _pred auf den letzten link. Dieser _head link ist essentziell für zb Count(), da intern immer ein "solange weitermachen, bis der aktuell zu prüfende link = _head ist" vorherrscht. Dies muss umbedingt mit geändert werden: Liste1._head._pred = Letzter link liste 2 liste2.LastLink()._succ = head liste 1 Meine funktion: BlitzMax: [AUSKLAPPEN]
Ein paar anmerkungen: Der kommentarbetzen ernhält die erste variante wie ich es getestet hab. Ist nur sch... unleserlich gewesen. Ich lasse es einfach mal drin. _Head._pred = Letzter link. Nach dem mergen wirds also der letzte link aus der einzufügenden liste sein. Dieser besagte letzte link muss nun auch ausserdem auf _head zeigen. DAS MERGEN AUF DIESE WEISE (ohne kopieren sämtlicher links) WIRD DIE 2te LISTE UNWEIGERLICH ZERSTÖREN!!! Nichtmal mehr toInsert.Clear() ging mehr. Deshalb habe ich sicherheitshalber die liste von hand "geleert", dh die Tlink kette entfernt, sodass die toInsert liste für das programm leer ist. Die Links sind derweil zwar noch im ram, sollten aber vom GarbageCollector entfernt werden. Hoffe ich konnte helfen. Wenns zu undeutlich war, einfach nochmal nachfragen. Ps: Tut mir leid, das sibly & co so bescheuerte kurznamen gewählt haben.. _pred und _succ sind irgendwie nicht aussagekräftig für mich :3 Meine erkenntnis: _pred = vorgänger link _succ = nachfolger link _head = masterlink, welcher sowohl auf den letzten wie auf den ersten link einer liste zeigt. |
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich halte das Verbinden per umschreiben der _head etc.-fields btw für wesentlich dreckiger als das kurze umcasten in ein Array und zussammenführen in dieser Form, da hier keine Liste zerstört (und somit Datenmüll) wird. | ||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
der punkt geht an dich, BR ![]() allerdings ist beim umcasten in einen array wahrscheinlich mehr leistung gefordert, wie die kleinere liste durchgehen und den inhalt der größeren liste hinzuzufügen. Alles in allem kommts auf den nutzen an, wie ich feststellen musste. Wenn man, warum auch immer, 2 getrennte listen erschafft und am ende nur eine braucht (und deshalb mergen möchte), ist der umschreibe weg der _head links etc der schnellste, da hier praktisch nur 4 pointer geändert werden. Hier ist es egal, wie groß die listen sind. Alle anderen möglichkeiten (for each + addlast sowie 2 arrays erschaffen, zusammenfügen (braucht nochmal extrem, da 2 arrays addieren direkt den platz für die kombi fordert)) dauern länger je mehr objekte in liste 1, liste 2 bzw beim array weg in liste 1 + 2 sind. Kurzum: Muss jeder selbst wissen, ist alles ziemlich dreckig, auf seine art ![]() (habe eben überlegt, ob man nicht die schlüssel-links, sprich die zu kombinierenden sowie den letzten link der 2ten liste, nicht kopieren könnte. Das wäre ein 2schneidiges schwert: Das würde klappen, aber auch nur solange, wie die 2te liste unangetastet bleibt. und selbst wenn man ihr was hinzufügt, kanns noch klappen. wird aber der vorletzte link geändert, gibts krieg) |
||
![]() |
UNZ |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke erstmal,
die zweite implementierung von PhillipK war genau, was ich gesucht hatte. Das die Liste dabei draufgeht war mir klar aber ist für mich nicht relevant. Zur Zeit habe ich es auch in der Form Code: [AUSKLAPPEN] Local list1:TList = CreateList () Local list2:TList = CreateList() .... For Local obj:Object = EachIn list2 list1.addLast(obj) Next bei mir umgesetzt. Allerdings hat das dann eine Laufzeit abhängig von der Länge der Liste2. Die konstante Laufzeit des "umsteckens" finde ich bei einer so wichtigen Datenstruktur wie einer Liste schöner. Danke dafür ![]() |
||
Das muss besser als perfekt! |
![]() |
UNZ |
![]() Antworten mit Zitat ![]() |
---|---|---|
Es gab noch ein Problem mit einer leeren Liste.
Hab es deshalb noch etwas überarbeitet. Code: [AUSKLAPPEN] Local list1:TList[1000] Local list2:TList[1000] For Local j:Int = 0 To 999 list1[j] = New TList For Local i:Int = 1 To 10 list1[j].AddLast("A"+i) Next list2[j] = New TList If j Mod 2 = 0 For Local i:Int = 1 To 10 list2[j].AddLast("B"+i) Next EndIf Next 'aufbau: ' _succ zeigt auf den nächsten Link. der letzte link hält immer _head (ein leerer link) als _succ. ' _head._pred zeigt auf den letzten, _head._succ zeigt auf den ersten link. 'link2._pred = link1 'erster link liste 2, vorgänger auf den letzten link liste1. 'link1._succ = link2 'letzter link liste 1, nachfolger auf den ersten link von liste2 . 'list1._head._pred = list2._head._succ 'den head von liste1 anpassen, sodass er auf den neuen, letzten link zeigt 'list2.lastLink()._succ = list1._head 'den nachfolger vom letzen link in liste2 auf den head von liste 1 setzen 'Nun sind die links neu verkabelt. 'Das ZERSTÖRT die zweite Liste, da diese nicht nutzbare links enthält. Function appendLists(lst:TList Var, toInsert:TList Var) If lst = Null Or toInsert = Null Return EndIf If toInsert.isEmpty() Return EndIf Local endLink:TLink= lst._head._pred Local startLink:TLink= toInsert._head._succ Local head:TLink= lst._head Local newEndLink:TLink= toInsert._head._pred endLink._succ = startLink startLink._pred = endLink newEndLink._succ = head head._pred = newEndLink 'destroy list toInsert._head._pred = toInsert._head toInsert._head._succ = toInsert._head toInsert = Null End Function GCCollect() Print GCMemAlloced() For Local i:Int = 0 To 999 appendLists(list1[i], list2[i]) 'list2[i] = Null Next Print GCMemAlloced() GCCollect() Print GCMemAlloced() If list1[0] Print("Anzahl einträge in list1: " + list1[0].Count() ) For Local str:String = EachIn list1[0] Print("String: " + str) Next EndIf '//////////////////////////////////////////////////////////////////////////////////////////////////////////// 'kann man so ins brl modul bei "linkedlist.bmx" werfen Rem bbdoc: Adds a list about: The last link of this list is headed to the first link of the list to add. THIS DESTROYS THE LIST TO ADD! end rem Rem Method append(toInsert:TList Var) 'no list to add If toInsert = Null Return EndIf 'list is empty -> add nothing If toInsert.isEmpty() Return EndIf Local endLink:TLink = _head._pred Local startLink:TLink = toInsert._head._succ Local head:TLink = _head Local newEndLink:TLink = toInsert._head._pred endLink._succ = startLink startLink._pred = endLink newEndLink._succ = head head._pred = newEndLink 'destroy list toInsert._head._pred = toInsert._head toInsert._head._succ = toInsert._head toInsert = Null End Method end rem |
||
Das muss besser als perfekt! |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group