Doubly-linked list/Traversal: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(38 intermediate revisions by 26 users not shown)
Line 1:
{{task|Data Structures}}[[Category:Iteration]]
[[Category:Iteration]]
 
Traverse from the beginning of a [[Doubly-linked list/Definition|doubly-linked list]] to the end, and from the end to the beginning.
 
 
{{Template:See also lists}}
<br><br>
 
=={{header|Action!}}==
The user must type in the monitor the following command after compilation and before running the program!<pre>SET EndProg=*</pre>
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang="action!">CARD EndProg ;required for ALLOCATE.ACT
 
INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program!
 
DEFINE PTR="CARD"
DEFINE NODE_SIZE="6"
TYPE ListNode=[INT data PTR prv,nxt]
 
ListNode POINTER listBegin,listEnd
 
PROC Append(INT v)
ListNode POINTER n
 
n=Alloc(NODE_SIZE)
n.data=v
n.prv=listEnd
n.nxt=0
IF listEnd THEN
listEnd.nxt=n
ELSE
listBegin=n
FI
listEnd=n
RETURN
 
PROC Clear()
ListNode POINTER n,next
 
n=listBegin
WHILE n
DO
next=n.nxt
Free(n,NODE_SIZE)
n=next
OD
listBegin=0
listEnd=0
RETURN
 
PROC ForwardTraverse()
ListNode POINTER n
 
n=listBegin
PrintE("Forward traverse:")
Print("(")
WHILE n
DO
PrintI(n.data)
IF n.nxt THEN
Print(", ")
FI
n=n.nxt
OD
PrintE(")")
RETURN
 
PROC BackwardTraverse()
ListNode POINTER n
 
n=listEnd
PrintE("Backward traverse")
Print("(")
WHILE n
DO
PrintI(n.data)
IF n.prv THEN
Print(", ")
FI
n=n.prv
OD
PrintE(")")
RETURN
 
PROC Main()
INT i
Put(125) PutE() ;clear screen
AllocInit(0)
listBegin=0
listEnd=0
 
FOR i=0 TO 50
DO
Append(i*i)
OD
ForwardTraverse()
PutE()
BackwardTraverse()
 
Clear()
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Doubly-linked_list_traversal.png Screenshot from Atari 8-bit computer]
<pre>
Forward traverse:
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361,
400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296,
1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500)
 
Backward traverse
(2500, 2401, 2304, 2209, 2116, 2025, 1936, 1849, 1764, 1681, 1600, 1521, 1444, 1369, 1296,
1225, 1156, 1089, 1024, 961, 900, 841, 784, 729, 676, 625, 576, 529, 484, 441, 400, 361,
324, 289, 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1, 0)
</pre>
 
=={{header|Ada}}==
{{works with|Ada 2005}}
<langsyntaxhighlight Adalang="ada">with Ada.Containers.Doubly_Linked_Lists;
with Ada.Text_IO;
 
Line 31 ⟶ 144:
My_List.Reverse_Iterate (Print'Access);
Ada.Text_IO.New_Line;
end Traversing;</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
LinkedList.alg:<langsyntaxhighlight lang="algol68"># Node struct - contains next and prev NODE pointers and DATA #
MODE NODE = STRUCT(
DATA data,
Line 122 ⟶ 235:
REF NODE travel := head OF list;
WHILE travel ISNT REF NODE(NIL) DO
list visit(data OF travel); # call user defined visit #
travel := next OF travel
OD
Line 135 ⟶ 248:
travel := prev OF travel
OD
)</langsyntaxhighlight>
 
main.alg:<langsyntaxhighlight lang="algol68">PR READ "LinkedList.alg" PR;
 
MODE EMPLOYEE = STRUCT(STRING name, INT salary, INT years);
Line 179 ⟶ 292:
PURGE list;
forward traversal(list)
)</langsyntaxhighlight>
{{out}}
<pre>
Line 195 ⟶ 308:
YEARS : +40
</pre>
 
=={{header|ALGOL W}}==
Using the element type and insertion routine from the Doubly Linked List/Eleemnt Insertion task.
<syntaxhighlight lang="algolw">begin
% record type to hold an element of a doubly linked list of integers %
record DListIElement ( reference(DListIElement) prev
; integer iValue
; reference(DListIElement) next
);
% additional record types would be required for other element types %
% inserts a new element into the list, before e %
reference(DListIElement) procedure insertIntoDListIBefore( reference(DListIElement) value e
; integer value v
);
begin
reference(DListIElement) newElement;
newElement := DListIElement( null, v, e );
if e not = null then begin
% the element we are inserting before is not null %
reference(DListIElement) ePrev;
ePrev := prev(e);
prev(newElement) := ePrev;
prev(e) := newElement;
if ePrev not = null then next(ePrev) := newElement
end if_e_ne_null ;
newElement
end insertIntoDListiAfter ;
 
begin
reference(DListIElement) head, e, last;
head := null;
head := insertIntoDListIBefore( head, 1701 );
head := insertIntoDListIBefore( head, 9000 );
e := insertIntoDListIBefore( next(head), 90210 );
e := insertIntoDListIBefore( next(e), 4077 );
e := head;
last := null;
write( "Forward:" );
while e not = null do begin
write( i_w := 1, s_w := 0, " ", iValue(e) );
last := e;
e := next(e)
end while_e_ne_null ;
write( "Backward:" );
e := last;
while e not = null do begin
write( i_w := 1, s_w := 0, " ", iValue(e) );
last := e;
e := prev(e)
end while_e_ne_null
end
end.</syntaxhighlight>
{{out}}
<pre>
Forward:
9000
90210
4077
1701
Backward:
1701
4077
90210
9000
</pre>
 
=={{header|Applesoft BASIC}}==
<syntaxhighlight lang="gwbasic"> 100 REM BUILD THE LIST
110 FOR I = 20 TO 40 STEP 10
120 LET S$ = STR$ (I): GOSUB 260"APPEND"
130 NEXT I
140 REM TRAVERSE FORWARDS
150 LET N = HEAD
160 FOR Q = 1 TO 1
170 IF N < > NIL THEN PRINT S$(N)" ";:N = N(N):Q = 0
180 NEXT Q
190 PRINT
200 REM TRAVERSE BACKWARDS
210 LET N = TAIL
220 FOR Q = 1 TO 1
230 IF N < > NIL THEN PRINT S$(N)" ";:N = P(N):Q = 0
240 NEXT Q
250 END
260 REM APPEND S$
270 LET NIL = - 1
280 LET P(L) = NIL
290 LET N(L) = NIL
300 REM TRAVERSE UNTIL LAST NODE FOUND
310 FOR Q = 1 TO 1
320 IF N(N) < > NIL THEN N = N(N):Q = 0
330 NEXT Q
340 REM NEW NODE
350 LET S$(L) = S$
360 LET N(L) = NIL
370 IF N < > L THEN P(L) = N
380 REM POINT THE LAST NODE AT THE NEW NODE
390 IF N < > L THEN N(N) = L
400 LET TAIL = L
410 LET N = TAIL
420 LET L = L + 1
430 RETURN</syntaxhighlight>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
/* program transDblList.s */
/* REMARK 1 : this program use routines in a include file
see task Include a file language arm assembly
for the routine affichageMess conversion10S
see at end of this program the instruction include */
 
/* Constantes */
.equ STDOUT, 1 @ Linux output console
.equ EXIT, 1 @ Linux syscall
.equ READ, 3
.equ WRITE, 4
 
/*******************************************/
/* Structures */
/********************************************/
/* structure Doublylinkedlist*/
.struct 0
dllist_head: @ head node
.struct dllist_head + 4
dllist_tail: @ tail node
.struct dllist_tail + 4
dllist_fin:
/* structure Node Doublylinked List*/
.struct 0
NDlist_next: @ next element
.struct NDlist_next + 4
NDlist_prev: @ previous element
.struct NDlist_prev + 4
NDlist_value: @ element value or key
.struct NDlist_value + 4
NDlist_fin:
/* Initialized data */
.data
szMessInitListe: .asciz "List initialized.\n"
szMessListInv: .asciz "Display list inverse :\n"
szCarriageReturn: .asciz "\n"
szMessErreur: .asciz "Error detected.\n"
/* datas message display */
szMessResult: .ascii "Result value :"
sValue: .space 12,' '
.asciz "\n"
/* UnInitialized data */
.bss
dllist1: .skip dllist_fin @ list memory place
 
/* code section */
.text
.global main
main:
ldr r0,iAdrdllist1
bl newDList @ create new list
ldr r0,iAdrszMessInitListe
bl affichageMess
ldr r0,iAdrdllist1 @ list address
mov r1,#10 @ value
bl insertHead @ insertion at head
cmp r0,#-1
beq 99f
ldr r0,iAdrdllist1
mov r1,#20
bl insertTail @ insertion at tail
cmp r0,#-1
beq 99f
ldr r0,iAdrdllist1 @ list address
mov r1,#10 @ value to after insered
mov r2,#15 @ new value
bl insertAfter
cmp r0,#-1
beq 99f
ldr r0,iAdrdllist1 @ list address
mov r1,#20 @ value to after insered
mov r2,#25 @ new value
bl insertAfter
cmp r0,#-1
beq 99f
ldr r0,iAdrdllist1
bl transHeadTail @ display value head to tail
ldr r0,iAdrszMessListInv
bl affichageMess
ldr r0,iAdrdllist1
bl transTailHead @ display value tail to head
b 100f
99:
ldr r0,iAdrszMessErreur
bl affichageMess
100: @ standard end of the program
mov r7, #EXIT @ request to exit program
svc 0 @ perform system call
iAdrszMessInitListe: .int szMessInitListe
iAdrszMessErreur: .int szMessErreur
iAdrszMessListInv: .int szMessListInv
iAdrszCarriageReturn: .int szCarriageReturn
iAdrdllist1: .int dllist1
/******************************************************************/
/* create new list */
/******************************************************************/
/* r0 contains the address of the list structure */
newDList:
push {r1,lr} @ save registers
mov r1,#0
str r1,[r0,#dllist_tail]
str r1,[r0,#dllist_head]
pop {r1,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* list is empty ? */
/******************************************************************/
/* r0 contains the address of the list structure */
/* r0 return 0 if empty else return 1 */
isEmpty:
//push {r1,lr} @ save registers
ldr r0,[r0,#dllist_head]
cmp r0,#0
movne r0,#1
//pop {r1,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* insert value at list head */
/******************************************************************/
/* r0 contains the address of the list structure */
/* r1 contains value */
insertHead:
push {r1-r4,lr} @ save registers
mov r4,r0 @ save address
mov r0,r1 @ value
bl createNode
cmp r0,#-1 @ allocation error ?
beq 100f
ldr r2,[r4,#dllist_head] @ load address first node
str r2,[r0,#NDlist_next] @ store in next pointer on new node
mov r1,#0
str r1,[r0,#NDlist_prev] @ store zero in previous pointer on new node
str r0,[r4,#dllist_head] @ store address new node in address head list
cmp r2,#0 @ address first node is null ?
strne r0,[r2,#NDlist_prev] @ no store adresse new node in previous pointer
streq r0,[r4,#dllist_tail] @ else store new node in tail address
100:
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* insert value at list tail */
/******************************************************************/
/* r0 contains the address of the list structure */
/* r1 contains value */
insertTail:
push {r1-r4,lr} @ save registers
mov r4,r0 @ save list address
mov r0,r1 @ value
bl createNode @ new node
cmp r0,#-1
beq 100f @ allocation error
ldr r2,[r4,#dllist_tail] @ load address last node
str r2,[r0,#NDlist_prev] @ store in previous pointer on new node
mov r1,#0 @ store null un next pointer
str r1,[r0,#NDlist_next]
str r0,[r4,#dllist_tail] @ store address new node on list tail
cmp r2,#0 @ address last node is null ?
strne r0,[r2,#NDlist_next] @ no store address new node in next pointer
streq r0,[r4,#dllist_head] @ else store in head list
100:
pop {r1-r4,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* insert value after other element */
/******************************************************************/
/* r0 contains the address of the list structure */
/* r1 contains value to search*/
/* r2 contains value to insert */
insertAfter:
push {r1-r5,lr} @ save registers
mov r4,r0
bl searchValue @ search node with this value in r1
cmp r0,#-1
beq 100f @ not found -> error
mov r5,r0 @ save address of node find
mov r0,r2 @ new value
bl createNode @ create new node
cmp r0,#-1
beq 100f @ allocation error
ldr r2,[r5,#NDlist_next] @ load pointer next of find node
str r0,[r5,#NDlist_next] @ store new node in pointer next
str r5,[r0,#NDlist_prev] @ store address find node in previous pointer on new node
str r2,[r0,#NDlist_next] @ store pointer next of find node on pointer next on new node
cmp r2,#0 @ next pointer is null ?
strne r0,[r2,#NDlist_prev] @ no store address new node in previous pointer
streq r0,[r4,#dllist_tail] @ else store in list tail
100:
pop {r1-r5,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* search value */
/******************************************************************/
/* r0 contains the address of the list structure */
/* r1 contains the value to search */
/* r0 return address of node or -1 if not found */
searchValue:
push {r2,lr} @ save registers
ldr r0,[r0,#dllist_head] @ load first node
1:
cmp r0,#0 @ null -> end search not found
moveq r0,#-1
beq 100f
ldr r2,[r0,#NDlist_value] @ load node value
cmp r2,r1 @ equal ?
beq 100f
ldr r0,[r0,#NDlist_next] @ load addresse next node
b 1b @ and loop
100:
pop {r2,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* transversal for head to tail */
/******************************************************************/
/* r0 contains the address of the list structure */
transHeadTail:
push {r2,lr} @ save registers
ldr r2,[r0,#dllist_head] @ load first node
1:
ldr r0,[r2,#NDlist_value]
ldr r1,iAdrsValue
bl conversion10S
ldr r0,iAdrszMessResult
bl affichageMess
ldr r2,[r2,#NDlist_next]
cmp r2,#0
bne 1b
100:
pop {r2,lr} @ restaur registers
bx lr @ return
iAdrszMessResult: .int szMessResult
iAdrsValue: .int sValue
/******************************************************************/
/* transversal for tail to head */
/******************************************************************/
/* r0 contains the address of the list structure */
transTailHead:
push {r2,lr} @ save registers
ldr r2,[r0,#dllist_tail] @ load last node
1:
ldr r0,[r2,#NDlist_value]
ldr r1,iAdrsValue
bl conversion10S
ldr r0,iAdrszMessResult
bl affichageMess
ldr r2,[r2,#NDlist_prev]
cmp r2,#0
bne 1b
100:
pop {r2,lr} @ restaur registers
bx lr @ return
/******************************************************************/
/* Create new node */
/******************************************************************/
/* r0 contains the value */
/* r0 return node address or -1 if allocation error*/
createNode:
push {r1-r7,lr} @ save registers
mov r4,r0 @ save value
@ allocation place on the heap
mov r0,#0 @ allocation place heap
mov r7,#0x2D @ call system 'brk'
svc #0
mov r5,r0 @ save address heap for output string
add r0,#NDlist_fin @ reservation place one element
mov r7,#0x2D @ call system 'brk'
svc #0
cmp r0,#-1 @ allocation error
beq 100f
mov r0,r5
str r4,[r0,#NDlist_value] @ store value
mov r2,#0
str r2,[r0,#NDlist_next] @ store zero to pointer next
str r2,[r0,#NDlist_prev] @ store zero to pointer previous
100:
pop {r1-r7,lr} @ restaur registers
bx lr @ return
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
.include "../affichage.inc"
 
</syntaxhighlight>
 
=={{header|AutoHotkey}}==
see [[Doubly-linked list/AutoHotkey]]
 
=={{header|Axe}}==
<syntaxhighlight lang="axe">LINK(L₁,1)→A
LINK(L₁+10,2)→B
LINK(L₁+50,3)→C
INSERT(A,B)
INSERT(A,C)
 
A→I
While I≠0
Disp VALUE(I)▶Dec,i
NEXT(I)→I
End
 
Disp "-----",i
 
B→I
While I≠0
Disp VALUE(I)▶Dec,i
PREV(I)→I
End</syntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> DIM node{pPrev%, pNext%, iData%}
DIM a{} = node{}, b{} = node{}, c{} = node{}
Line 238 ⟶ 760:
here.pNext% = new{}
ENDPROC
</syntaxhighlight>
</lang>
Output:
<pre>Traverse forwards:
Line 250 ⟶ 772:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">// A doubly linked list of strings;
#include <stdio.h>
#include <stdlib.h>
Line 377 ⟶ 899:
//uhhh-- delete list??
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
 
Line 406 ⟶ 928:
}
}
}</langsyntaxhighlight>
Output:
<pre>
Line 420 ⟶ 942:
e
h</pre>
 
=={{header|C++}}==
{{works with|C++11}}
<syntaxhighlight lang="cpp">#include <iostream>
#include <list>
 
int main ()
{
std::list<int> numbers {1, 5, 7, 0, 3, 2};
for(const auto& i: numbers)
std::cout << i << ' ';
std::cout << '\n';
}</syntaxhighlight>
{{out}}
<pre>
1 5 7 0 3 2
</pre>
 
=={{header|Clojure}}==
Given the definition in [[../Definition#Clojure]],
<langsyntaxhighlight Clojurelang="clojure">(def dl (double-list [:a :b :c :d]))
;=> #'user/dl
 
Line 440 ⟶ 979:
;=> #:double_list.Node{:prev #<Object...>, :next #<Object...>, :data :c, :key #<Object...>}
;=> #:double_list.Node{:prev #<Object...>, :next #<Object...>, :data :b, :key #<Object...>}
;=> #:double_list.Node{:prev nil, :next #<Object...>, :data :a, :key #<Object...>})</langsyntaxhighlight>
 
=={{header|D}}==
===Standard Doubly-linked List===
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.container, std.range;
 
Line 451 ⟶ 990:
dll[].writeln;
dll[].retro.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>ABCD
Line 458 ⟶ 997:
===User-defined Doubly-linked list===
Same output.
<langsyntaxhighlight lang="d">struct Node(T) {
T data;
typeof(this)* prev, next;
Line 487 ⟶ 1,026:
p.data.write;
writeln;
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
<langsyntaxhighlight lang="delphi">uses system ;
 
type
Line 515 ⟶ 1,054:
while not (pList^.prev = NIL) do pList := pList^.prev ;
 
end;</langsyntaxhighlight>
 
=={{header|E}}==
{{incorrect|E|Doesn't work, probably due to a bug in the list definition: runs over the beginning of the list. Needs debugging.}}
Given the definition in [[../Definition#E]],
<langsyntaxhighlight lang="e">def traverse(list) {
var node := list.atFirst()
while (true) {
Line 538 ⟶ 1,077:
}
}
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">? def list := makeDLList()
# value: <>
 
Line 553 ⟶ 1,092:
3
2
1</langsyntaxhighlight>
 
=={{header|Erlang}}==
The task in [[Doubly-linked_list/Element_insertion]] uses traversal as proof that the insertion worked.
 
=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
open System.Collections.Generic
 
let first (l: LinkedList<char>) = l.First
let last (l: LinkedList<char>) = l.Last
 
let next (l: LinkedListNode<char>) = l.Next
let prev (l: LinkedListNode<char>) = l.Previous
 
let traverse g f (ls: LinkedList<char>) =
let rec traverse (l: LinkedListNode<char>) =
match l with
| null -> ()
| _ ->
printf "%A" l.Value
traverse (f l)
traverse (g ls)
 
let traverseForward = traverse first next
let traverseBackward = traverse last prev
 
let cs = LinkedList(['a'..'z'])
 
traverseForward cs
printfn ""
traverseBackward cs
</syntaxhighlight>
{{out}}
<pre>
'a''b''c''d''e''f''g''h''i''j''k''l''m''n''o''p''q''r''s''t''u''v''w''x''y''z'
'z''y''x''w''v''u''t''s''r''q''p''o''n''m''l''k''j''i''h''g''f''e''d''c''b''a'
</pre>
 
=={{header|Fortran}}==
see [[Doubly-linked list/Definition#Fortran]]
 
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">Dim As Integer i, MiLista()
 
For i = 0 To Int(Rnd * 100)+25
Redim Preserve MiLista(i)
MiLista(i) = Rnd * 314
Next
 
'Tour from the beginning
For i = Lbound(MiLista) To Ubound(MiLista)
Print MiLista(i)
Next i
 
Print
'Travel from the end
For i = Ubound(MiLista) To Lbound(MiLista) Step -1
Print MiLista(i)
Next i
Sleep</syntaxhighlight>
 
 
=={{header|Go}}==
Line 565 ⟶ 1,160:
 
Also note that there is a doubly linked list in the Go standard library in package container/list.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 626 ⟶ 1,221:
}
fmt.Println("")
}</langsyntaxhighlight>
Output:
<pre>
Line 634 ⟶ 1,229:
From tail: B C A
</pre>
 
=={{header|Groovy}}==
<syntaxhighlight lang="groovy">class DoubleLinkedListTraversing {
static void main(args) {
def linkedList = (1..9).collect() as LinkedList
 
linkedList.each {
print it
}
 
println()
 
linkedList.reverseEach {
print it
}
}
}</syntaxhighlight>
 
{{out}}
<pre>123456789
987654321</pre>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">main = print . traverse True $ create [10,20,30,40]
 
data DList a = Leaf | Node { prev::(DList a), elt::a, next::(DList a) }
Line 654 ⟶ 1,270:
traverse _ Leaf = []
traverse True (Node l v Leaf) = v : v : traverse False l
traverse dir (Node l v r) = v : traverse dir (if dir then r else l)</langsyntaxhighlight>
 
==Icon and {{header|Unicon}}==
Uses Unicon classes.
<langsyntaxhighlight Uniconlang="unicon">class DoubleLink (value, prev_link, next_link)
 
# insert given node after this one, removing its existing connections
Line 705 ⟶ 1,321:
every (node := l2.traverse_backwards ()) do
write (node.value)
end</langsyntaxhighlight>
 
Output:
Line 720 ⟶ 1,336:
 
=={{header|J}}==
<langsyntaxhighlight lang="j">traverse=:1 :0
work=. result=. conew 'DoublyLinkedListHead'
current=. y
Line 727 ⟶ 1,343:
end.
result
)</langsyntaxhighlight>
 
This traverses a doubly linked list, applying the verb u to the data in each list element and creates a new doubly linked list containing the results. A reference to the new doubly linked list is returned.
 
=={{header|Java}}==
{{works with|Java|8 or higher}}
<lang java>import java.util.LinkedList;
 
<syntaxhighlight lang="java">
public static void main(){
package com.rosettacode;
LinkedList<String> LL = new LinkedList<String>();
traverse(LL.iterator());
traverse(LL.descendingIterator());
}
 
import java.util.LinkedList;
private static void traverse(Iterator<String> iter){
import java.util.stream.Collectors;
while(iter.hasNext()){
import java.util.stream.IntStream;
iter.next();
 
}
public class DoubleLinkedListTraversing {
}</lang>
 
public static void main(String[] args) {
 
final LinkedList<String> doubleLinkedList =
IntStream.range(1, 10)
.mapToObj(String::valueOf)
.collect(Collectors.toCollection(LinkedList::new));
 
doubleLinkedList.iterator().forEachRemaining(System.out::print);
System.out.println();
doubleLinkedList.descendingIterator().forEachRemaining(System.out::print);
}
}</syntaxhighlight>
 
{{out}}
<pre>123456789
987654321</pre>
 
=={{header|JavaScript}}==
See [[Doubly-Linked List (element)#JavaScript]]. The <code>traverse()</code> and <code>print()</code> functions have been inherited from [[Singly-Linked List (traversal)#JavaScript]].
<langsyntaxhighlight lang="javascript">DoublyLinkedList.prototype.getTail = function() {
var tail;
this.traverse(function(node){tail = node;});
Line 764 ⟶ 1,394:
var head = createDoublyLinkedListFromArray([10,20,30,40]);
head.print();
head.getTail().printBackward();</langsyntaxhighlight>
 
outputs:
Line 776 ⟶ 1,406:
10</pre>
Uses the <code>print()</code> function from [[Rhino]] or [[SpiderMonkey]].
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">mutable struct DLNode{T}
value::T
pred::Union{DLNode{T}, Nothing}
succ::Union{DLNode{T}, Nothing}
DLNode(v) = new{typeof(v)}(v, nothing, nothing)
end
 
function insertpost(prevnode, node)
succ = prevnode.succ
prevnode.succ = node
node.pred = prevnode
node.succ = succ
if succ != nothing
succ.pred = node
end
node
end
 
first(nd) = (while nd.pred != nothing nd = nd.prev end; nd)
last(nd) = (while nd.succ != nothing nd = nd.succ end; nd)
 
function printconnected(nd; fromtail = false)
if fromtail
nd = last(nd)
print(nd.value)
while nd.pred != nothing
nd = nd.pred
print(" -> $(nd.value)")
end
else
nd = first(nd)
print(nd.value)
while nd.succ != nothing
nd = nd.succ
print(" -> $(nd.value)")
end
end
println()
end
 
node1 = DLNode(1)
node2 = DLNode(2)
node3 = DLNode(3)
insertpost(node1, node2)
insertpost(node2, node3)
print("From beginning to end: "); printconnected(node1)
print("From end to beginning: "); printconnected(node1, fromtail = true)
</syntaxhighlight> {{output}} <pre>
From beginning to end: 1 -> 2 -> 3
From end to beginning: 3 -> 2 -> 1
</pre>
 
=={{header|Kotlin}}==
To complete this task, we just need to add a couple of traversal functions to the class we defined in the [[Doubly-linked list/Definition]] task:
<syntaxhighlight lang="scala">// version 1.1.2
 
class LinkedList<E> {
class Node<E>(var data: E, var prev: Node<E>? = null, var next: Node<E>? = null) {
override fun toString(): String {
val sb = StringBuilder(this.data.toString())
var node = this.next
while (node != null) {
sb.append(" -> ", node.data.toString())
node = node.next
}
return sb.toString()
}
}
 
var first: Node<E>? = null
var last: Node<E>? = null
 
fun addFirst(value: E) {
if (first == null) {
first = Node(value)
last = first
}
else {
val node = first!!
first = Node(value, null, node)
node.prev = first
}
}
 
fun addLast(value: E) {
if (last == null) {
last = Node(value)
first = last
}
else {
val node = last!!
last = Node(value, node, null)
node.next = last
}
}
 
fun insert(after: Node<E>?, value: E) {
if (after == null)
addFirst(value)
else if (after == last)
addLast(value)
else {
val next = after.next
val new = Node(value, after, next)
after.next = new
if (next != null) next.prev = new
}
}
 
override fun toString() = first.toString()
 
fun firstToLast() = first?.toString() ?: ""
 
fun lastToFirst(): String {
if (last == null) return ""
val sb = StringBuilder(last.toString())
var node = last!!.prev
while (node != null) {
sb.append(" -> ", node.data.toString())
node = node.prev
}
return sb.toString()
}
}
 
fun main(args: Array<String>) {
val ll = LinkedList<Int>()
ll.addFirst(1)
ll.addLast(4)
ll.insert(ll.first, 2)
ll.insert(ll.last!!.prev, 3)
println("First to last : ${ll.firstToLast()}")
println("Last to first : ${ll.lastToFirst()}")
}</syntaxhighlight>
 
{{out}}
<pre>
First to last : 1 -> 2 -> 3 -> 4
Last to first : 4 -> 3 -> 2 -> 1
</pre>
 
=={{header|Lua}}==
Begin with this: [[Doubly-linked_list/Definition#Lua]], then extend with this:
<syntaxhighlight lang="lua">--------------
-- TRAVERSAL:
--------------
List.iterateForward = function(self)
local function iter(self, node)
if node then return node.next else return self.head end
end
return iter, self, nil
end
List.iterateReverse = function(self)
local function iter(self, node)
if node then return node.prev else return self.tail end
end
return iter, self, nil
end
 
---------
-- TEST:
---------
local list = List()
for i = 1, 5 do list:insertTail(i) end
io.write("Forward: ") for node in list:iterateForward() do io.write(node.data..",") end print()
io.write("Reverse: ") for node in list:iterateReverse() do io.write(node.data..",") end print()</syntaxhighlight>
{{out}}
<pre>Forward: 1,2,3,4,5,
Reverse: 5,4,3,2,1,</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
struct block,nxt as ulong,prev as ulong,nm as char[20],age as long'Our structure of the blocks in our list.
 
Line 925 ⟶ 1,726:
calldll #kernel32,"HeapDestroy",hHeap as ulong,ret as void
end sub
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">type
List[T] = object
head, tail: Node[T]
Line 1,007 ⟶ 1,808:
 
for i in l.traverseBackward():
echo "< ", i</langsyntaxhighlight>
 
=={{header|Oberon-2}}==
<syntaxhighlight lang="oberon2">
MODULE Collections;
IMPORT Box;
 
TYPE
Action = PROCEDURE (o: Box.Object);
 
PROCEDURE (dll: DLList) GoForth*(do: Action);
VAR
iter: Node;
BEGIN
iter := dll.first;
WHILE iter # NIL DO
do(iter.value);
iter := iter.next
END
END GoForth;
 
PROCEDURE (dll: DLList) GoBack*(do: Action);
VAR
iter: Node;
BEGIN
ASSERT(dll.last # NIL);
iter := dll.last;
WHILE iter # NIL DO
do(iter.value);
iter := iter.prev
END
END GoBack;
 
END Collections.
</syntaxhighlight>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
class Traverse {
function : Main(args : String[]) ~ Nil {
Line 1,035 ⟶ 1,870:
}
}
</syntaxhighlight>
</lang>
 
<pre>
Line 1,050 ⟶ 1,885:
5
100
</pre>
 
=={{header|Oforth}}==
 
Complete definition is here : [[../Definition#Oforth]]
 
Defining #forEachNext and #forEachPrev allow to traverse this double linked list using #forEach: and #revEach: syntax
 
<syntaxhighlight lang="oforth">DList method: forEachNext
dup ifNull: [ drop @head ifNull: [ false ] else: [ @head @head true] return ]
next dup ifNull: [ drop false ] else: [ dup true ] ;
 
DList method: forEachPrev
dup ifNull: [ drop @tail ifNull: [ false ] else: [ @tail @tail true] return ]
prev dup ifNull: [ drop false ] else: [ dup true ] ;
 
: test
| dl n |
DList new ->dl
dl insertFront("A")
dl insertBack("B")
dl head insertAfter(DNode new("C", null , null))
 
"Traversal (beginning to end) : " println
dl forEach: n [ n . ]
 
"\nTraversal (end to beginning) : " println
dl revEach: n [ n . ] ;</syntaxhighlight>
 
{{out}}
<pre>
>test
Traversal (beginning to end) :
A C B
Traversal (end to beginning) :
B C A ok
</pre>
 
=={{header|Oz}}==
Warning: Highly unidiomatic code. (Use built-in lists instead.)
<langsyntaxhighlight lang="oz">declare
proc {Walk Node Action}
case Node of nil then skip
Line 1,107 ⟶ 1,978:
{InsertAfter A C}
{Walk A Show}
{WalkBackwards A Show}</langsyntaxhighlight>
 
=={{header|Pascal}}==
See [[Doubly-linked_list/Traversal#Delphi | Delphi]]
 
=={{header|Perl 6}}==
=={{header|Phix}}==
Since the list routines are supplied by the generic roles defined in [[Doubly-linked_list/Definition#Perl_6]], it suffices to say:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang perl6>say $dll.list;
<span style="color: #008080;">enum</span> <span style="color: #000000;">NEXT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">PREV</span><span style="color: #0000FF;">,</span><span style="color: #000000;">DATA</span>
say $dll.reverse;</lang>
<span style="color: #008080;">constant</span> <span style="color: #000000;">empty_dll</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}}</span>
These automatically return just the payloads, hiding the elements containing the forward and backward pointers.
<span style="color: #004080;">sequence</span> <span style="color: #000000;">dll</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">empty_dll</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">insert_after</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">prv</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">][</span><span style="color: #000000;">PREV</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">dll</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dll</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prv</span><span style="color: #0000FF;">,</span><span style="color: #000000;">data</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">prv</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">prv</span><span style="color: #0000FF;">][</span><span style="color: #000000;">NEXT</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dll</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">][</span><span style="color: #000000;">PREV</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dll</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">insert_after</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"ONE"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">insert_after</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"TWO"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">insert_after</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"THREE"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">dll</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">DATA</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dll</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #000000;">NEXT</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"=="</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #000000;">PREV</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
{{2,4},{3,1,"ONE"},{4,2,"TWO"},{1,3,"THREE"}}
"ONE"
"TWO"
"THREE"
"=="
"THREE"
"TWO"
"ONE"
</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp"># Print the elements a doubly-linked list
(de 2print (DLst)
(for (L (car DLst) L (cddr L))
Line 1,128 ⟶ 2,038:
(for (L (cdr DLst) L (cadr L))
(printsp (car L)) )
(prinl) )</langsyntaxhighlight>
Output for the example data produced in
[[Doubly-linked list/Definition#PicoLisp]] and
Line 1,146 ⟶ 2,056:
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">/* To implement a doubly-linked list -- i.e., a 2-way linked list. */
doubly_linked_list: proc options (main);
 
Line 1,178 ⟶ 2,088:
t => back_pointer = tail; /* Point the new tail back to the old */
/* tail. */
tail = t; /* Point at tehthe new tail. */
tail => fwd_pointer = bind(:node, null:);
/* Set the tail link to NULL */
Line 1,202 ⟶ 2,112:
t = t => back_pointer;
end;
end doubly_linked_list;</langsyntaxhighlight>
Output:
<pre>
Line 1,229 ⟶ 2,139:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">NewList MyData.i() ; Create a double linked list holding a single value (integer)
 
;Set up a randomly long linked list in the range 25-125 elements
Line 1,247 ⟶ 2,157:
Repeat
Debug MyData() ; Present the value in the current cell
Until Not PreviousElement(MyData())</langsyntaxhighlight>
 
=={{header|Python}}==
This provides two solutions. One that explicitly builds a linked list and traverses it two ways, and another which uses pythons combined list/array class. Unless two lists explicitly needed to be spliced together in O(1) time, or a double linked list was needed for some other reason, most python programmers would probably use the second solution.
<langsyntaxhighlight lang="python">class List:
def __init__(self, data, next=None, prev=None):
self.data = data
Line 1,279 ⟶ 2,189:
while node != None:
print(node.data)
node = node.prev</langsyntaxhighlight>
 
This produces the desired output. However, I expect most python programmers would do the following instead:
 
<langsyntaxhighlight lang="python">l = [ 10, 20, 30, 40 ]
for i in l:
print(i)
for i in reversed(l): # reversed produces an iterator, so only O(1) memory is used
print(i)</langsyntaxhighlight>
 
Double-ended queues in python are provided by the collections.deque class and the array/list type can perform all the operations of a C++ vector (and more), so building one's own doubly-linked list would be restricted to very specialized situations.
Line 1,296 ⟶ 2,206:
These functions traverse the list in the two directions.
They create a native (singly-linked) list by adding to the front, so they traverse in the reverse order from the desired result order.
<langsyntaxhighlight lang="racket">(define (dlist-elements dlist)
(let loop ([elements '()] [dlink (dlist-tail dlist)])
(if dlink
Line 1,306 ⟶ 2,216:
(if dlink
(loop (cons (dlink-content dlink) elements) (dlink-next dlink))
elements)))</langsyntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
 
Since the list routines are supplied by the generic roles defined in [[Doubly-linked_list/Definition#Raku]], it suffices to say:
<syntaxhighlight lang="raku" line>say $dll.list;
say $dll.reverse;</syntaxhighlight>
These automatically return just the payloads, hiding the elements containing the forward and backward pointers.
 
=={{header|REXX}}==
REXX doesn't have linked lists, as there are no pointers (or handles).
However, linked lists can be simulated with lists in REXX.
<langsyntaxhighlight lang="rexx">/*REXX program that implements various List Manager functions. */
/*┌────────────────────────────────────────────────────────────────────┐
┌─┘ Functions of the List Manager └─┐
Line 1,389 ⟶ 2,307:
$.@=_
call @adjust
return</langsyntaxhighlight>
'''output'''
<pre style="height:30ex;overflow:scroll">
Line 1,425 ⟶ 2,343:
─── showing list ───
Oy! Was it a black cat I saw there, in the shadows, stalking its prey (and next
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Doubly-linked list/Traversal
 
trav = [123, 789, 456]
travfor = sort(trav)
see "Traverse forwards:" + nl
see travfor
see nl
travback = reverse(travfor)
see "Traverse backwards:" + nl
see travback
see nl
</syntaxhighlight>
Output:
<pre>
Traverse forwards:
123
456
789
 
Traverse backwards:
789
456
123
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">class DListNode
def get_tail
# parent class (ListNode) includes Enumerable, so the find method is available to us
Line 1,442 ⟶ 2,387:
head = DListNode.from_array([:a, :b, :c])
head.each {|node| p node.value}
head.get_tail.each_previous {|node| p node.value}</langsyntaxhighlight>
 
=={{header|Salmon}}==
Without explicit type information:
<langsyntaxhighlight Salmonlang="salmon">class item(init_data)
{
variable next,
Line 1,487 ⟶ 2,432:
follow.data!
step
follow := follow.previous;;</langsyntaxhighlight>
 
With explicit type information:
<langsyntaxhighlight Salmonlang="salmon">class item(init_data : string)
{
variable next: item | {null},
Line 1,531 ⟶ 2,476:
follow.data!
step
follow := follow.previous;;</langsyntaxhighlight>
 
Both of these produce the following output:
Line 1,552 ⟶ 2,497:
a
</pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">import java.util
 
object DoublyLinkedListTraversal extends App {
 
private val ll = new util.LinkedList[String]
 
private def traverse(iter: util.Iterator[String]) =
while (iter.hasNext) iter.next
 
traverse(ll.iterator)
traverse(ll.descendingIterator)
}</syntaxhighlight>
 
=={{header|Tcl}}==
Assuming that the <code>List</code> class from [[Doubly-Linked List (element)#Tcl|this other task]] is already present...
<langsyntaxhighlight lang="tcl"># Modify the List class to add the iterator methods
oo::define List {
method foreach {varName script} {
Line 1,578 ⟶ 2,537:
$first foreach char { puts $char }
puts "Backward..."
$last revforeach char { puts $char }</langsyntaxhighlight>
Which produces this output:
<pre>Forward...
Line 1,590 ⟶ 2,549:
b
a</pre>
 
=={{header|Wren}}==
{{libheader|Wren-llist}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./llist" for DLinkedList
import "./fmt" for Fmt
 
// create a new doubly-linked list and add the first 50 positive integers to it
var dll = DLinkedList.new(1..50)
 
// traverse the doubly-linked list from head to tail
for (i in dll) {
Fmt.write("$4d ", i)
if (i % 10 == 0) System.print()
}
System.print()
// traverse the doubly-linked list from tail to head
for (i in dll.reversed) {
Fmt.write("$4d ", i)
if (i % 10 == 1) System.print()
}</syntaxhighlight>
 
{{out}}
<pre>
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
 
50 49 48 47 46 45 44 43 42 41
40 39 38 37 36 35 34 33 32 31
30 29 28 27 26 25 24 23 22 21
20 19 18 17 16 15 14 13 12 11
10 9 8 7 6 5 4 3 2 1
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">def \Node\ Prev, Data, Next; \Element (Node) definition
def SizeofInt = 4;
 
proc Insert(NewNode, Node); \Insert NewNode after Node
int NewNode, Node, NextNode;
[NextNode:= Node(Next);
NextNode(Prev):= NewNode;
NewNode(Next):= NextNode;
NewNode(Prev):= Node;
Node(Next):= NewNode;
];
 
int Head(3), Tail(3); \Doubly linked list definition
int N, NewNode, Node;
[\Further define (initialize) the doubly linked list
Head(Next):= Tail;
Tail(Prev):= Head;
\Insert some Nodes containing square data
for N:= 1 to 10 do
[NewNode:= Reserve(3*SizeofInt);
NewNode(Data):= N*N;
Insert(NewNode, Head);
];
\Traverse list from Head to Tail
Node:= Head(Next);
while Node # Tail do
[IntOut(0, Node(Data)); ChOut(0, ^ );
Node:= Node(Next);
];
CrLf(0);
\Traverse list from Tail to Head
Node:= Tail(Prev);
while Node # Head do
[IntOut(0, Node(Data)); ChOut(0, ^ );
Node:= Node(Prev);
];
CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
100 81 64 49 36 25 16 9 4 1
1 4 9 16 25 36 49 64 81 100
</pre>
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">class Node{
fcn init(_value,_prev=Void,_next=Void)
{ var value=_value, prev=_prev, next=_next; }
fcn toString{ value.toString() }
fcn append(value){
b,c := Node(value,self,next),next;
next=b;
if(c) c.prev=b;
b
}
}</syntaxhighlight>
<syntaxhighlight lang="zkl">a,c := Node("a"), a.append("b").append("c");
n:=a; while(n){ print(n," "); n=n.next }
println();
n:=c; while(n){ print(n," "); n=n.prev }
println();</syntaxhighlight>
{{out}}
<pre>
a b c
c b a
</pre>
 
{{omit from|ACL2}}
9,476

edits