Verkettete Liste: Unterschied zwischen den Versionen
Sn (Diskussion | Beiträge) (→Suchen: Laufzeit) |
Sn (Diskussion | Beiträge) (Umstellung auf GraphViz begonnen) |
||
Zeile 8: | Zeile 8: | ||
Die einfachsten Fälle sind die leere Liste: | Die einfachsten Fälle sind die leere Liste: | ||
< | <graphviz format="svg"> | ||
digraph EmptyList { | |||
fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif" | |||
node [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
edge [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
layout="neato"; | |||
subgraph cluster_empty { | |||
head [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>null</TD></TR></TABLE>>, shape="none", pos="0,0!"]; | |||
tail [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD>null</TD></TR></TABLE>>, shape="none", pos="1,0!"]; | |||
} | |||
} | } | ||
</graphviz> | |||
</ | |||
... und eine einelementige Liste: | ... und eine einelementige Liste: | ||
< | <graphviz format="svg"> | ||
digraph ListOneElement { | |||
fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif" | |||
node [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
edge [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
layout="neato"; | |||
subgraph cluster_node { | |||
head [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>42</TD></TR></TABLE>>, shape="none", pos="0,0!"]; | |||
tail [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD>null</TD></TR></TABLE>>, shape="none", pos="1,0!"]; | |||
} | |||
} | } | ||
</graphviz> | |||
</ | |||
An diese Liste können nun weitere Elemente angefügt werden, indem schrittweise neue Listen erzeugt werden: | An diese Liste können nun weitere Elemente angefügt werden, indem schrittweise neue Listen erzeugt werden: | ||
< | <graphviz format="svg"> | ||
digraph ListTwoElements { | |||
compound="true" | |||
fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif" | |||
node [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
edge [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
layout="neato"; | |||
subgraph cluster_node1 { | |||
head1 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>42</TD></TR></TABLE>>, shape="none", pos="0,0!"]; | |||
tail1 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD PORT="ptr"> </TD></TR></TABLE>>, shape="none", pos="1,0!"]; | |||
} | |||
subgraph cluster_node2 { | |||
head2 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>23</TD></TR></TABLE>>, shape="none", pos="3,0!"]; | |||
tail2 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD>null</TD></TR></TABLE>>, shape="none", pos="4,0!"]; | |||
} | |||
tail1:ptr -> head2 [lhead="cluster_node2"]; | |||
} | } | ||
</graphviz> | |||
<graphviz format="svg"> | |||
digraph ListTwoElements { | |||
compound="true" | |||
fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif" | |||
node [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
edge [fontname="Source Sans Pro,Linux Biolinum,Helvetica,Arial,sans-serif"] | |||
layout="neato"; | |||
subgraph cluster_node1 { | |||
head1 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>42</TD></TR></TABLE>>, shape="none", pos="0,0!"]; | |||
tail1 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD PORT="ptr"> </TD></TR></TABLE>>, shape="none", pos="1,0!"]; | |||
} | |||
subgraph cluster_node2 { | |||
head2 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>23</TD></TR></TABLE>>, shape="none", pos="3,0!"]; | |||
tail2 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD PORT="ptr"> </TD></TR></TABLE>>, shape="none", pos="4,0!"]; | |||
} | |||
subgraph cluster_node3 { | |||
head3 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>head</TD></TR><TR><TD>69</TD></TR></TABLE>>, shape="none", pos="6,0!"]; | |||
tail3 [label=<<TABLE BORDER="0" CELLSPACING="0" CELLBORDER="1"><TR><TD>tail</TD></TR><TR><TD>null</TD></TR></TABLE>>, shape="none", pos="7,0!"]; | |||
} | |||
tail1:ptr -> head2 [lhead="cluster_node2"]; | |||
tail2:ptr -> head3 [lhead="cluster_node3"]; | |||
} | } | ||
</graphviz> | |||
</ | |||
{{Todo|Sn}} | |||
} | |||
} | |||
== Operationen == | == Operationen == | ||
Zeile 101: | Zeile 97: | ||
hide empty description | hide empty description | ||
skinparam linetype ortho | skinparam linetype ortho | ||
state | state Node1 { | ||
state "head" as h1 | state "head" as h1 | ||
h1: 42 | h1: 42 | ||
Zeile 107: | Zeile 103: | ||
h1 -[hidden]right-> t1 | h1 -[hidden]right-> t1 | ||
} | } | ||
state | state Node2 { | ||
state "head" as h2 | state "head" as h2 | ||
h2: 23 | h2: 23 | ||
Zeile 113: | Zeile 109: | ||
h2 -[hidden]right-> t2 | h2 -[hidden]right-> t2 | ||
} | } | ||
state | state Node3 { | ||
state "head" as h3 | state "head" as h3 | ||
h3: 69 | h3: 69 | ||
Zeile 127: | Zeile 123: | ||
t4: null | t4: null | ||
} | } | ||
t1 --[bold]right-> | state List | ||
t2 --[bold]right-> | List -[bold]right-> Node1 | ||
t1 --[bold]right-> Node2 | |||
t2 --[bold]right-> Node3 | |||
t3 --[hidden]right-> newElement | t3 --[hidden]right-> newElement | ||
@enduml | @enduml | ||
Zeile 139: | Zeile 137: | ||
hide empty description | hide empty description | ||
skinparam linetype ortho | skinparam linetype ortho | ||
state | state Node1 { | ||
state "head" as h1 | state "head" as h1 | ||
h1: 42 | h1: 42 | ||
Zeile 145: | Zeile 143: | ||
h1 -[hidden]right-> t1 | h1 -[hidden]right-> t1 | ||
} | } | ||
state | state Node2 { | ||
state "head" as h2 | state "head" as h2 | ||
h2: 23 | h2: 23 | ||
Zeile 151: | Zeile 149: | ||
h2 -[hidden]right-> t2 | h2 -[hidden]right-> t2 | ||
} | } | ||
state | state Node3 { | ||
state "head" as h3 | state "head" as h3 | ||
h3: 69 | h3: 69 | ||
Zeile 164: | Zeile 162: | ||
t4: null | t4: null | ||
} | } | ||
t1 --[bold]right-> | state List | ||
t2 --[bold]right-> | List -[bold]right-> Node1 | ||
t1 --[bold]right-> Node2 | |||
t2 --[bold]right-> Node3 | |||
t3 --[bold,#00B169]right-> newElement | t3 --[bold,#00B169]right-> newElement | ||
@enduml | @enduml | ||
Zeile 176: | Zeile 176: | ||
hide empty description | hide empty description | ||
skinparam linetype ortho | skinparam linetype ortho | ||
state | state Node1 { | ||
state "head" as h1 | state "head" as h1 | ||
h1: 42 | h1: 42 | ||
Zeile 182: | Zeile 182: | ||
h1 -[hidden]right-> t1 | h1 -[hidden]right-> t1 | ||
} | } | ||
state | state Node2 { | ||
state "head" as h2 | state "head" as h2 | ||
h2: 23 | h2: 23 | ||
Zeile 188: | Zeile 188: | ||
h2 -[hidden]right-> t2 | h2 -[hidden]right-> t2 | ||
} | } | ||
state | state Node3 { | ||
state "head" as h3 | state "head" as h3 | ||
h3: 69 | h3: 69 | ||
Zeile 202: | Zeile 202: | ||
t4: null | t4: null | ||
} | } | ||
t1 -[bold]right-> | state List | ||
List -[bold]right-> Node1 | |||
t1 -[bold]right-> Node2 | |||
t1 -[hidden]down-> newElement | t1 -[hidden]down-> newElement | ||
newElement -[hidden]up-> | newElement -[hidden]up-> Node2 | ||
t2 -[bold]right-> | t2 -[bold]right-> Node3 | ||
@enduml | @enduml | ||
</uml> | </uml> | ||
Zeile 214: | Zeile 216: | ||
@startuml | @startuml | ||
hide empty description | hide empty description | ||
state | state Node1 { | ||
state "head" as h1 | state "head" as h1 | ||
h1: 42 | h1: 42 | ||
Zeile 221: | Zeile 223: | ||
} | } | ||
state | state Node2 { | ||
state "head" as h2 | state "head" as h2 | ||
h2: 23 | h2: 23 | ||
Zeile 227: | Zeile 229: | ||
h2 -[hidden]right-> t2 | h2 -[hidden]right-> t2 | ||
} | } | ||
state | state Node3 { | ||
state "head" as h3 | state "head" as h3 | ||
h3: 69 | h3: 69 | ||
Zeile 241: | Zeile 243: | ||
t4: null | t4: null | ||
} | } | ||
t1 -[#lightgray]right> | t1 -[#lightgray]right> Node2 | ||
t1 -[bold,#00B169]-> newElement | t1 -[bold,#00B169]-> newElement | ||
t4 -[bold,#00B169]down-> | t4 -[bold,#00B169]down-> Node2 | ||
t2 -[bold]right> | t2 -[bold]right> Node3 | ||
Node1 -[hidden]up-> Node2 | |||
' Diese Kombination von Befehlen ergibt das gewünschte Layout. | ' Diese Kombination von Befehlen ergibt das gewünschte Layout. | ||
' Keine Ahnung warum. Die Layout-Algorithmen von PlantUML sind fubar. | ' Keine Ahnung warum. Die Layout-Algorithmen von PlantUML sind fubar. | ||
' Also fuck it. Ich hasse es, aber es bleibt so. | ' Also fuck it. Ich hasse es, aber es bleibt so. | ||
state List | |||
List -[bold]right-> Node1 | |||
@enduml | @enduml | ||
</uml> | </uml> |
Version vom 24. September 2024, 06:18 Uhr
Eine verkettete Liste (engl. linked list) ist eine Datenstruktur, die beliebig viele Elemente in linearer Form speichern kann, d.h. zu jedem Element außer dem letzten existiert genau ein Nachfolger und zu jedem Element außer dem ersten existiert genau ein Vorgänger.
Verkettete Listen sind rekursiv definiert und bestehen aus zwei Teilen:
- einem Objekt, genannt
head
; das ist das erste Element der (Teil-)Liste - einer verketteten Liste, genannt
tail
; das ist der gesamte Rest der Liste
Die einfachsten Fälle sind die leere Liste:
... und eine einelementige Liste:
An diese Liste können nun weitere Elemente angefügt werden, indem schrittweise neue Listen erzeugt werden:
Dieser Abschnitt wird gerade von Sn überarbeitet
Operationen
Suchen
Selbst wenn die Liste sortiert ist, kann nur dadurch nach Elementen suchen, dass man die ganze Liste von vorn nach hinten durchgeht. Da jedes Element nur mit seinem direkten Nachfolger verbunden ist, können auch keine Algorithmen wie die Binäre Suche eingesetzt werden. Die Suche in einer verketteten Liste hat damit eine Laufzeit in .
Einfügen
Am Ende einer Liste kann man einfach ein neues Element anfügen, indem man ein neues Listen-Objekt mit einem Eintrag erzeugt:
... und dann den tail
des letzten Listenelements darauf zeigen lässt.
In der Mitte einer Liste kann man einfach ein neues Element anfügen, indem man ein neues Listen-Objekt mit einem Eintrag erzeugt:
... und dann den tail
des vorhergehenden Listenelements darauf zeigen lässt.
In diesem Artikel oder Abschnitt fehlen noch folgende wichtige Informationen:
Hilf dem KGS-Wiki, indem du sie recherchierst und einfügst.