Seite 1 von 1
Element von einer LinkedList in eine andere schieben
Verfasst: 05.02.2021 20:22
von jacdelad
Hallo,
ich hab leider nichts zufriedenstellendes gefunden: Wie kann ich ein Element von einer LimkedList in eine andere schieben? Mit einfachen Variablen ist das natürlich einfach, wenn ich aber eine Struktur benutze muss ich alle Elemente der Struktur bearbeiten. Vielleicht geht das ja einfacher.
Edit: Ach verdammt, Rechtschreibfehler im Titel...
Re: Element von einer LinkedList in eine andere schieben
Verfasst: 05.02.2021 20:39
von NicTheQuick
jacdelad hat geschrieben:Edit: Ach verdammt, Rechtschreibfehler im Titel...
Jetzt nicht mehr
Zur Frage:
Ein effizientes Verschieben ist meines Wissens nicht ohne Hacks möglich. Und mit Hacks meine ich die inneren Datenstrukturen der eingebauten LinkedLists zu ändern.
Was dir aber helfen könnte ist vielleicht CopyStructure() bzw. die native Zuweisung von strukturierten Variablen:
Code: Alles auswählen
Structure myStructure
i.i
s.s
EndStructure
NewList a.myStructure()
NewList b.myStructure()
For i = 0 To 9
If AddElement(a())
a()\i = i
a()\s = "Item " + i
EndIf
If AddElement(b())
b()\i = i + 10
b()\s = "Item " + Str(i + 10)
EndIf
Next
Procedure MoveElementBetweenLists(List a.myStructure(), List b.myStructure())
If AddElement(b())
b() = a()
DeleteElement(a())
EndIf
EndProcedure
; Select first element in list a() to move before the first element of list b()
FirstElement(a())
ResetList(b())
MoveElementBetweenLists(a(), b())
Debug "a()"
ForEach a()
Debug a()\s
Next
Debug "b()"
ForEach b()
Debug b()\s
Next
Re: Element von einer LinkedList in eine andere schieben
Verfasst: 06.02.2021 16:20
von ST4242
Hallo,
eine möglichkeit ist die Listen mit Zeigern zu erzeugen, dann muß nur der Zeiger in die andere Liste gegeben werden.
Allerdings sollte man bei dieser Lösung gut im Umgang mit Speicherbereichen sein, da am Ende der Speicher für jedes Element auch immer manuell freigeben werden muß.
Weiterhin ist so möglich das in beiden Listen auf die gleichen Daten verwiesen wird.
Wie gesagt ist nur für etwas erfahrene Programmierer
Gruß
Code: Alles auswählen
Structure s1
a.i
b.i
s.s
EndStructure
NewList *l1.s1()
NewList *l2.s1()
For i =1 To 20
AddElement(*l1())
; *l1()=AllocateStructure(s1)
*l1()=AllocateMemory(SizeOf(s1))
*l1()\a=i
*l1()\b=i+100
*l1()\s ="!text "+Str(i)
Next i
FirstElement(*l1())
SelectElement(*l1(),4)
AddElement(*l2())
*l2()=*l1()
DeleteElement(*l1())
Debug *l2()\s
Re: Element von einer LinkedList in eine andere schieben
Verfasst: 06.02.2021 23:57
von helpy
Eine andere etwas umständliche Möglichkeit das aktuelle Element von Liste A ans Ende von Liste B zu verschieben, wäre die Verwendung von MoveElement, SplitList und MergeList:
Code: Alles auswählen
EnableExplicit
Structure tTest
Name.s
Value.i
ValueString.s
EndStructure
Procedure DebugList(List dl.tTest(), ListName.s)
Debug ""
Debug ListName
Debug "-----"
ForEach dl()
Debug dl()\Name + " / " + Str(dl()\Value) + " / " + dl()\ValueString
Next
EndProcedure
Procedure MoveCurrentElement(List src.tTest(), List target.tTest())
Protected NewList tmp.tTest()
MoveElement(src(), #PB_List_Last)
SplitList(src(), tmp(), #False)
MergeLists(tmp(), target(), #PB_List_Last)
EndProcedure
NewList listA.tTest()
NewList listB.tTest()
Define i, j
For i = 1 To 10
AddElement(listA())
With listA()
\Name = "Element " + Str(i)
\Value = Random(1000000,1)
\ValueString = Str(\Value)
EndWith
Next i
DebugList(listA(), "Liste A")
DebugList(listB(), "Liste B")
For i = 10 To 1 Step -1
j = Random(i,1)
SelectElement(listA(), j-1)
MoveCurrentElement(listA(), listB())
Next i
DebugList(listA(), "Liste A")
DebugList(listB(), "Liste B")
Re: Element von einer LinkedList in eine andere schieben
Verfasst: 07.02.2021 23:38
von helpy
Ich habe mal einen Test gemacht und wollte wissen, wie schnell Elemente auf diese etwas umständliche Art verschoben werden. Test mit etwas geänderter Methode:
Code: Alles auswählen
EnableExplicit
Structure tTest
Name.s
Value.i
ValueString.s
EndStructure
Procedure MoveCurrentElement(List src.tTest(), List target.tTest())
Static NewList tmp.tTest()
MoveElement(src(), #PB_List_Last)
SplitList(src(), tmp())
MergeLists(tmp(), target())
EndProcedure
NewList listA.tTest()
NewList listB.tTest()
Define i, j
#ListSize = 1000000
For i = 1 To #ListSize
AddElement(listA())
With listA()
\Name = "Element " + Str(i)
\Value = Random(10000000,1)
\ValueString = Str(\Value)
EndWith
Next i
MessageRequester("Start moving elements!",
"Listsize of listA: " + Str(ListSize(listA())) + #CRLF$ +
"Listsize of listB: " + Str(ListSize(listB())) + #CRLF$)
Define start = ElapsedMilliseconds()
LastElement(listA())
For i = #ListSize To 1 Step -1
MoveCurrentElement(listA(), listB())
Next i
Define ende = ElapsedMilliseconds()
MessageRequester("Move " + Str(#ListSize) + " elements!",
"Moved all elements to other list in " + Str(ende-start) + " ms!" + #CRLF$ +
"Listsize of listA: " + Str(ListSize(listA())) + #CRLF$ +
"Listsize of listB: " + Str(ListSize(listB())) + #CRLF$)
(1) Auf meinem Notebook (Core i3, 2,3 GHz) werden 1.000.000 Elemente innerhalb von 41ms verschoben.
Die Methode mit dem "Static NewList tmp.tTest()" sollte nicht in Threads verwendet werden.
(2) Mit "Protected NewList tmp.tTest()" braucht die Methode bereits über 1,7s.
(3) Alternativ mit "Threaded NewList tmp.tTest()" (definiert außerhalb der Methode) braucht es bei mir 56ms.
Methoden 1 + 3 sind aber gar nicht so langsam
