Doubly-linked list/Definition: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by 5 users not shown)
Line 12:
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}}
<langsyntaxhighlight Actionlang="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!
Line 164:
TestAddAfter(7,listEnd)
TestClear()
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Doubly-linked_list_definition.png Screenshot from Atari 8-bit computer]
Line 198:
{{works with|ALGOL 68|Revision 1 - one extension to language used - PRAGMA READ - a non standard feature similar to C's #include directive.}}{{works with|ALGOL 68G|Any - tested with release algol68g-2.7}}
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}}
'''File: prelude/Doubly-linked_list_Link.a68'''<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
COMMENT REQUIRES:
MODE VALUE = ~;
Line 212:
MODE LINK = REF LINKNEW;
 
SKIP</langsyntaxhighlight>'''File: prelude/Doubly-linked_list_Operator.a68'''<langsyntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #
MODE LISTNEW = LINKNEW;
MODE LIST = REF LISTNEW;
Line 259:
link ISNT LINK(self);
 
SKIP</langsyntaxhighlight>'''File: test/Doubly-linked_list_Operator_Usage.a68'''<langsyntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
MODE VALUE = STRING; # user defined data type #
Line 303:
OD;
print(new line)
)</langsyntaxhighlight>
{{out}}
<pre>
Line 313:
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program defDblList.s */
Line 552:
bx lr @ return
 
</syntaxhighlight>
</lang>
 
=={{header|ATS}}==
Line 562:
 
The reason for this complication is that, in ATS, a linear object can be treated as "mutable", without resorting to embedded C code. One cost of this is that an object of a linear type has to be freed explicitly. However, if it is cast to an "ordinary" (nonlinear) type, a garbage collector to handle freeing the object. Such casting is what I have done.
 
In the following, the doubly linked list and its nodes are not distinct types. The nodes form a circle, but they do not form a circular list, because one of the nodes is a "root" node that holds no value, cannot be deleted, and is marked as special.
 
Here is ''dllist.sats''.
<langsyntaxhighlight ATSlang="ats">(********************************************************************)
(* The public interface *)
 
abstype dllist_t (t : t@ype+, is_root : bool) (* An abstract type. *)
typedef dllist_t (t : t@ype+) = [b : bool] dllist_t (t, b)
 
Line 633 ⟶ 635:
(dl : list (t, n)) : dllist_t t
 
(********************************************************************)</langsyntaxhighlight>
 
 
Here is ''dllist.dats''.
<langsyntaxhighlight ATSlang="ats">#define ATS_DYNLOADFLAG 0
 
#include "share/atspre_staload.hats"
Line 844 ⟶ 846:
types is bypassed by these interface template functions.
 
ThisA garbage collector, of course, is thenecessary situation withfor a great many programming
programming languages, and with more of them all the time. So it is nothing
nothing extraordinary.
 
The usual garbage collector to use with ATS2 (Postiats) is Boehm
Line 1,017 ⟶ 1,019:
end
 
(********************************************************************)</langsyntaxhighlight>
 
 
And here is ''dllist-demo.dats''.
<langsyntaxhighlight ATSlang="ats">#include "share/atspre_staload.hats"
 
staload "dllist.sats"
Line 1,140 ⟶ 1,142:
val _ = print_forwards dl
val _ = println! ()
}</langsyntaxhighlight>
 
 
Line 1,163 ⟶ 1,165:
=={{header|C}}==
 
<langsyntaxhighlight lang="c">/* double linked list */
#include <stdio.h>
#include <stdlib.h>
Line 1,319 ⟶ 1,321:
n->succ->pred = n->pred;
return n;
}</langsyntaxhighlight>
 
Simple test:
 
<langsyntaxhighlight lang="c">/* basic test */
 
struct IntNode {
Line 1,357 ⟶ 1,359:
free(lista);
}
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
Line 1,367 ⟶ 1,369:
Though mutating the ''structure'' of a list can only be done through the <code>LinkedList<T></code> class, mutating the values contained by the nodes of a list is done through its individual <code>LinkedListNode<T></code> instances, as the <code>LinkedListNode<T>.Next</code>.Value property is settable.
 
<langsyntaxhighlight Clang="c sharp">using System.Collections.Generic;
 
class Program
Line 1,392 ⟶ 1,394:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,409 ⟶ 1,411:
=={{header|C++}}==
{{works with|C++11}}
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <list>
 
Line 1,422 ⟶ 1,424:
std::cout << i << ' ';
std::cout << '\n';
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,429 ⟶ 1,431:
 
=={{header|Clojure}}==
<langsyntaxhighlight Clojurelang="clojure">(ns double-list)
 
(defprotocol PDoubleList
Line 1,539 ⟶ 1,541:
(defmethod print-method Node [n w]
(print-method (symbol "#:double_list.Node") w)
(print-method (into {} (dissoc n :m)) w))</langsyntaxhighlight>
Usage:
<langsyntaxhighlight Clojurelang="clojure">(use 'double-list)
;=> nil
(def dl (double-list (range 10)))
Line 1,562 ⟶ 1,564:
;=> #:double_list.Node{:prev #<Object ...>, :next #<Object ...>, :data 1, :key #<Object ...>}
(get-prev *1)
;=> #:double_list.Node{:prev #<Object ...>, :next #<Object ...>, :data 1, :key #<Object ...>}</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
 
<langsyntaxhighlight lang="lisp">(defstruct dlist head tail)
(defstruct dlink content prev next)
 
Line 1,613 ⟶ 1,615:
acc
(extract-values (dlink-next dlink) (cons (dlink-content dlink) acc)))))
(reverse (extract-values (dlist-head dlist) nil))))</langsyntaxhighlight>
 
The following produces <code>(1 2 3 4)</code>.
 
<langsyntaxhighlight lang="lisp">(let ((dlist (make-dlist)))
(insert-head dlist 1)
(insert-tail dlist 4)
Line 1,624 ⟶ 1,626:
(bad-link (insert-before dlist next-to-last 42)))
(remove-link dlist bad-link))
(print (dlist-elements dlist)))</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio;
 
class LinkedList(T)
Line 1,734 ⟶ 1,736:
}
writeln;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,745 ⟶ 1,747:
{{libheader| boost.LinkedList}}[[https://github.com/MaiconSoft/DelphiBoostLib]]
{{Trans|C#}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Doubly_linked;
 
Line 1,784 ⟶ 1,786:
List.Free;
Readln;
end.</langsyntaxhighlight>
 
=={{header|E}}==
<langsyntaxhighlight lang="e">def makeDLList() {
def firstINode
def lastINode
Line 1,893 ⟶ 1,895:
}
return dlList
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">? def list := makeDLList()
# value: <>
 
Line 1,925 ⟶ 1,927:
? for x in 11..20 { list.push(x) }
? list
# value: <0, 1, 5, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20></langsyntaxhighlight>
 
=={{header|Erlang}}==
As with [[Singly-linked_list/Element_insertion]] a process is used to get mutability in Erlang's single assignment world.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( doubly_linked_list ).
 
Line 1,997 ⟶ 1,999:
loop_foreach_previous( _Fun, noprevious ) -> ok;
loop_foreach_previous( Fun, Next ) -> Next ! {foreach_previous, Fun}.
</syntaxhighlight>
</lang>
 
=={{header|F Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">type DListAux<'T> = {mutable prev: DListAux<'T> option; data: 'T; mutable next: DListAux<'T> option}
type DList<'T> = {mutable front: DListAux<'T> option; mutable back: DListAux<'T> option} //'
 
Line 2,027 ⟶ 2,029:
if link.next = dlist.back then addBack dlist elt else
let e = Some {prev=Some link; data=elt; next=link.next}
link.next <- e</langsyntaxhighlight>
 
=={{header|Fortran}}==
Tested with g95 and gfortran v. 4.6.
<langsyntaxhighlight lang="fortran">
module dlist
implicit none
Line 2,239 ⟶ 2,241:
call tidy(mydll)
end program dl
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,246 ⟶ 2,248:
Doubly-linked list has 5 element - bwd = 7, 5, 4, 3, 1
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="vb">Sub InsertaElto(lista() As String, posic As Integer = 1)
For i As Integer = Lbound(lista) To Ubound(lista)
If i = posic Then Swap lista(i), lista(Ubound(lista))
Next i
End Sub
 
Sub mostrarLista(lista() As String, titulo As String)
'display all elements from list of strings
Print !"\n"; titulo;
For i As Integer = Lbound(lista) To Ubound(lista)
Print lista(i); " ";
Next i
Print ""
End Sub
 
Dim As String arr() 'create a new list of strings
Dim As String elto 'items to add to the list
Dim As Integer j, c = 0
 
Restore datos
Do
Read elto : c += 1
If elto <> "EndOfData" Then Redim Preserve arr(c) : arr(c) = elto
Loop Until elto = "EndOfData"
 
Dim As Integer lb = Lbound(arr), ub = Ubound(arr)
Dim As String arrTMP(ub)
For j = lb To ub : arrTMP(ub-j) = arr(j)
Next j
For j = lb To ub : Swap arr(j), arrTMP(j)
Next j
mostrarLista(arr(),"Insertion at Head: ")
 
Erase arr
Restore datos
c = 0
Do
Read elto : c += 1
If elto <> "EndOfData" Then Redim Preserve arr(c) : arr(c) = elto
Loop Until elto = "EndOfData"
mostrarLista(arr(),"Insertion at Tail:")
 
Erase arr
Restore datos
c = 0
Do
Read elto : c += 1
If elto <> "EndOfData" Then Redim Preserve arr(c) : arr(c) = elto
Loop Until elto = "EndOfData"
InsertaElto(arr(), 3)
mostrarLista(arr(),"Insertion in Middle:")
 
Sleep
 
'the list of datos that will be added to the list
datos:
Data "One", "Two", "Three", "Four", "Five", "Six", "EndOfData"</syntaxhighlight>
{{out}}
<pre>Insertion at Head: Six Five Four Three Two One
Insertion at Tail: One Two Three Four Five Six
Insertion in Middle: One Two Six Four Five Three</pre>
 
=={{header|Go}}==
Go has nothing like an enforced invariant. Responsibility for preventing circular loops must be shared by all code that modifies the list. Given that, the following declaration ''enables'' code to do that efficiently.
<langsyntaxhighlight lang="go">type dlNode struct {
int
next, prev *dlNode
Line 2,261 ⟶ 2,326:
members map[*dlNode]int
head, tail **dlNode
}</langsyntaxhighlight>
Or, just use the [http://golang.org/pkg/container/list/#Element container/list] package:
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 2,280 ⟶ 2,345:
fmt.Println(e.Value)
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
For an efficient implementation, see the <code>Data.FDList</code> module provided by [http://hackage.haskell.org/package/liboleg liboleg]. But before using doubly linked lists at all, see [http://stackoverflow.com/questions/1844195/doubly-linked-list-in-a-purely-functional-programming-language this discussion on Stack Overflow].
 
<langsyntaxhighlight lang="haskell">import qualified Data.Map as M
 
type NodeID = Maybe Rational
Line 2,339 ⟶ 2,404:
fromList = foldr fcons empty
 
toList = map vNode . M.elems</langsyntaxhighlight>
 
An example of use:
 
<langsyntaxhighlight lang="haskell">main = putStrLn $ toList l
where l = mcons 'M' n1 n2 x
x = rcons 'Z' $ fcons 'a' $ fcons 'q' $ singleton 'w'
n1 = firstNode x
Just n2 = nextNode x n1</langsyntaxhighlight>
 
==Icon and {{header|Unicon}}==
Line 2,355 ⟶ 2,420:
The DoubleList is made from elements of DoubleLink. [[Doubly-Linked List (element)#Icon_and_Unicon]], [[Doubly-Linked List (element insertion)#Icon_and_Unicon]] and [[Doubly-Linked List (traversal)#Icon_and_Unicon]]
 
<syntaxhighlight lang="unicon">
<lang Unicon>
class DoubleList (item)
 
Line 2,394 ⟶ 2,459:
self.item := DoubleLink (value)
end
</syntaxhighlight>
</lang>
 
An <code>insert_before</code> method was added to the DoubleLink class:
 
<syntaxhighlight lang="unicon">
<lang Unicon>
# insert given node before this one, losing its existing connections
method insert_before (node)
Line 2,406 ⟶ 2,471:
self.prev_link := node
end
</syntaxhighlight>
</lang>
 
To test the double-linked list:
 
<syntaxhighlight lang="unicon">
<lang Unicon>
procedure main ()
dlist := DoubleList (5)
Line 2,423 ⟶ 2,488:
write (node.value)
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,493 ⟶ 2,558:
The <code>LinkedList<T></code> class is the Doubly-linked list implementation in Java. There are a large number of methods supporting the list. An example is shown below.
 
<langsyntaxhighlight lang="java">
import java.util.LinkedList;
 
Line 2,519 ⟶ 2,584:
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,538 ⟶ 2,603:
 
=={{header|Julia}}==
Regarding the avoidance or circular loops part of this task, a call to <syntaxhighlight lang ="julia">show(DLNode)</langsyntaxhighlight> reveals that Julia considers all of the nodes of doubly linked lists of this kind to contain circular references to their adjacent nodes.
<langsyntaxhighlight lang="julia">mutable struct DLNode{T}
value::T
pred::Union{DLNode{T}, Nothing}
Line 2,611 ⟶ 2,676:
delete(node4)
print("From end to beginning post deletion: "); printconnected(node1, fromtail = true)
</langsyntaxhighlight> {{output}} <pre>
First value is 1 and last value is 3
From beginning to end: 1 -> 4 -> 2 -> 3
Line 2,619 ⟶ 2,684:
=={{header|Kotlin}}==
Rather than use the java.util.LinkedList<E> class, we will write our own simple LinkedList<E> class for this task:
<langsyntaxhighlight lang="scala">// version 1.1.2
 
class LinkedList<E> {
Line 2,684 ⟶ 2,749:
ll.insert(ll.last!!.prev, 3)
println(ll)
}</langsyntaxhighlight>
 
{{out}}
Line 2,692 ⟶ 2,757:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">-- Doubly Linked List in Lua 6/15/2020 db
-------------------
-- IMPLEMENTATION:
Line 2,800 ⟶ 2,865:
local n222 = list:insertAfter(n22, 222) validate(list, "-1,0,1,11,111,2,22,222,3,33,4,44,444,5,55")
local n333 = list:insertBefore(n4, 333) validate(list, "-1,0,1,11,111,2,22,222,3,33,333,4,44,444,5,55")
local n555 = list:insertAfter(n55, 555) validate(list, "-1,0,1,11,111,2,22,222,3,33,333,4,44,444,5,55,555")</langsyntaxhighlight>
{{out}}
<pre>true
Line 2,835 ⟶ 2,900:
 
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Checkit {
Form 80, 50
Line 3,003 ⟶ 3,068:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">ds = CreateDataStructure["DoublyLinkedList"];
ds["Append", #] & /@ {1, 5, 7, 0, 3, 2};
ds["Prepend", 9];
Line 3,012 ⟶ 3,077:
(* This is adding at the end and then swap to insert in to the middle: *)
ds["Append", 14]; ds["SwapPart", Round[ds["Length"]/2], ds["Length"]];
ds["Elements"]</langsyntaxhighlight>
{{out}}
<pre>{9, 1, 5, 14, 0, 3, 2, 4, 7}</pre>
Line 3,018 ⟶ 3,083:
=={{header|Nim}}==
Nim has a doubly linked list already in the lists module of the standard library.
<langsyntaxhighlight lang="nim">type
List[T] = object
head, tail: Node[T]
Line 3,085 ⟶ 3,150:
l2.prepend newNode("hello")
l2.append newNode("world")
echo l2</langsyntaxhighlight>
{{out}}
<pre>15 -> 14 -> 12
Line 3,091 ⟶ 3,156:
 
=={{header|Oberon-2}}==
<langsyntaxhighlight lang="oberon2">
IMPORT Basic;
TYPE
Line 3,104 ⟶ 3,169:
size-: INTEGER;
END;
</syntaxhighlight>
</lang>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
use Collection;
 
Line 3,124 ⟶ 3,189:
while(list->Get() <> Nil);
}
}</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
<langsyntaxhighlight lang="oforth">Object Class new: DNode(value, mutable prev, mutable next)
DNode method: initialize := next := prev := value ;
Line 3,177 ⟶ 3,242:
dl insertBack("B")
dl head insertAfter(DNode new("C", null , null))
dl ;</langsyntaxhighlight>
 
{{out}}
Line 3,199 ⟶ 3,264:
| | | ---+---> end
+-----+-----+
<langsyntaxhighlight PicoLisplang="picolisp"># Build a doubly-linked list
(de 2list @
(let Prev NIL
Line 3,208 ⟶ 3,273:
(cons L Prev) ) ) )
 
(setq *DLst (2list 'was 'it 'a 'cat 'I 'saw))</langsyntaxhighlight>
For output of the example data, see [[Doubly-linked list/Traversal#PicoLisp]].
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
define structure
1 Node,
Line 3,218 ⟶ 3,283:
2 back_pointer handle(Node),
2 fwd_pointer handle(Node);
</syntaxhighlight>
</lang>
 
=={{header|PowerShell}}==
Create and populate the list:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$list = New-Object -TypeName 'Collections.Generic.LinkedList[PSCustomObject]'
 
Line 3,231 ⟶ 3,296:
 
$list
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,247 ⟶ 3,312:
</pre>
Insert a value at the head:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$list.AddFirst([PSCustomObject]@{ID=123; X=123;Y=123}) | Out-Null
 
$list
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,268 ⟶ 3,333:
</pre>
Insert a value in the middle:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$current = $list.First
 
Line 3,283 ⟶ 3,348:
 
$list
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,301 ⟶ 3,366:
</pre>
Insert a value at the end:
<syntaxhighlight lang="powershell">
<lang PowerShell>
$list.AddLast([PSCustomObject]@{ID=789; X=789;Y=789}) | Out-Null
 
$list
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,325 ⟶ 3,390:
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">DataSection
;the list of words that will be added to the list
words:
Line 3,392 ⟶ 3,457:
displayList(a(),"Insertion in Middle: ")
 
Repeat: Until Inkey() <> ""</langsyntaxhighlight>
{{out}}
<pre>
Line 3,409 ⟶ 3,474:
datatype. See [https://wiki.python.org/moin/TimeComplexity TimeComplexity].
 
<langsyntaxhighlight lang="python">
from collections import deque
 
Line 3,420 ⟶ 3,485:
for value in reversed(some_list):
print(value)
</syntaxhighlight>
</lang>
 
{{out}}
Line 3,449 ⟶ 3,514:
break links between nodes in other lists.
 
<langsyntaxhighlight lang="python">
"""A doubly-linked list. Requires Python >=3.7"""
from __future__ import annotations
Line 3,618 ⟶ 3,683:
self.size -= 1
return value
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
The following is a port of the Common Lisp solution. The ouput is '(1 2 3 4).
 
<langsyntaxhighlight lang="racket">
#lang racket
(define-struct dlist (head tail) #:mutable #:transparent)
Line 3,683 ⟶ 3,748:
(remove-link dlist bad-link))
(dlist-elements dlist))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
This shows a complete example. (Other entries in the section focus on aspects of this solution.)
<syntaxhighlight lang="raku" perl6line>role DLElem[::T] {
has DLElem[T] $.prev is rw;
has DLElem[T] $.next is rw;
Line 3,747 ⟶ 3,812:
 
say $dll.list; # 0 1 2 40 41 42
say $dll.reverse; # 42 41 40 2 1 0</langsyntaxhighlight>
{{out}}
<pre>0 1 2 40 41 42
Line 3,778 ⟶ 3,843:
REXX doesn't have linked lists, as there are no pointers (or handles).
<br>However, linked lists can be simulated with lists in REXX.
<langsyntaxhighlight lang="rexx">/*REXX program implements various List Manager functions (see the documentation above).*/
call sy 'initializing the list.' ; call @init
call sy 'building list: Was it a cat I saw' ; call @put "Was it a cat I saw"
Line 3,821 ⟶ 3,886:
/*──────────────────────────────────────────────────────────────────────────────────────*/
@show: procedure expose $.; parse arg k,m,dir; if dir==-1 & k=='' then k=$.#
m=p(m $.#); call @parms 'kmd'; say @get(k,m, dir); return</langsyntaxhighlight>
'''output'''
<pre style="height:30ex;overflow:scroll">
Line 3,860 ⟶ 3,925:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Doubly-linked list/Definition
 
Line 3,877 ⟶ 3,942:
svect = left(svect, len(svect) - 1)
see svect
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,896 ⟶ 3,961:
 
 
<langsyntaxhighlight lang="scheme">(cond-expand
(r7rs)
(chicken (import r7rs)))
Line 4,069 ⟶ 4,134:
 
(display "conversion from a list:")
(print-it (list->dllist (list "a" "b" "c")))</langsyntaxhighlight>
 
{{out}}
Line 4,086 ⟶ 4,151:
=={{header|Swift}}==
 
<syntaxhighlight lang="Swift">typealias NodePtr<T> = UnsafeMutablePointer<Node<T>>
 
class Node<T> {
Line 4,228 ⟶ 4,293:
list.remove(node!)
 
print(list)</langsyntaxhighlight>
 
{{out}}
Line 4,235 ⟶ 4,300:
[0, 1, 2, 3, 4, 5, 100, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 100, 6, 7, 8, 9]</pre>
 
{{works with|Swift|5.8}}
 
This version uses classes instead of structs and unsafe pointers. It thus obviates the need for explicit memory management and i, I think, a little cleaner.
 
Loops are avoided by handling the management of all links within the class itself.
 
<syntaxhighlight lang="Swift">public class DoublyLinkedList<Element>
{
public class Entry
{
// Each entry owns the next entry
public fileprivate(set) weak var prev: Entry?
public fileprivate(set) var next: Entry?
public let item: Element
 
init(prev: Entry? = nil, next: Entry? = nil, item: Element)
{
self.prev = prev
self.next = next
self.item = item
}
}
 
public init(){}
 
public private(set) var headEntry: Entry? = nil
public private(set) var tailEntry: Entry? = nil
 
public var head: Element? { headEntry?.item }
public var tail: Element? { tailEntry?.item }
 
public func append(item: Element)
{
let newEntry = Entry(prev: tailEntry, item: item)
if let tailEntry
{
tailEntry.next = newEntry
}
else
{
headEntry = newEntry
}
tailEntry = newEntry
}
 
public func prepend(item: Element)
{
let newEntry = Entry(next: headEntry, item: item)
if let headEntry
{
headEntry.prev = newEntry
}
else
{
tailEntry = newEntry
}
headEntry = newEntry
}
 
public func insert(item: Element, before: Entry)
{
let newEntry = Entry(next: before, item: item)
if let previous = before.prev
{
newEntry.prev = previous
previous.next = newEntry
}
else
{
headEntry = newEntry
}
newEntry.next = before
}
 
public func insert(item: Element, after: Entry)
{
let newEntry = Entry(prev: after, item: item)
if let next = after.next
{
newEntry.next = next
next.prev = newEntry
}
else
{
tailEntry = newEntry
}
after.next = newEntry
}
 
@discardableResult public func remove(entry: Entry) -> Element
{
if let prevEntry = entry.prev
{
prevEntry.next = entry.next
}
else
{
headEntry = entry.next
}
if let nextEntry = entry.next
{
nextEntry.prev = entry.prev
}
else
{
tailEntry = entry.prev
}
entry.prev = nil
entry.next = nil
return entry.item
}
}
 
extension DoublyLinkedList: CustomStringConvertible where Element: CustomStringConvertible
{
public var description: String
{
var array: [Element] = []
var currentEntry = headEntry
while let thisEntry = currentEntry
{
array.append(thisEntry.item)
currentEntry = thisEntry.next
}
return "[" + array.map({ $0.description }).joined(separator: ", ") + "]"
}
}
 
let list = DoublyLinkedList<Int>()
for i in 0 ... 5
{
list.append(item: i)
}
for i in 10 ... 15
{
list.prepend(item: i)
}
 
if let insertPoint = list.headEntry?.next?.next
{
list.insert(item: 99, after: insertPoint)
}
print("\(list)")
if let removePoint = list.headEntry?.next?.next?.next
{
let item = list.remove(entry: removePoint)
}
print("\(list)")
</syntaxhighlight>
 
{{out}}
<pre>
[15, 14, 13, 99, 12, 11, 10, 0, 1, 2, 3, 4, 5]
[15, 14, 13, 12, 11, 10, 0, 1, 2, 3, 4, 5]
</pre>
 
=={{header|Tcl}}==
Line 4,251 ⟶ 4,472:
See also [[Doubly-Linked List (element)]] for a TclOO-based version.
 
<langsyntaxhighlight Tcllang="tcl">package require Tcl 8.4
proc dl {_name cmd {where error} {value ""}} {
upvar 1 $_name N
Line 4,321 ⟶ 4,542:
}
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="tcl"># Testing code
set testcases [split {
dl D insert head foo
Line 4,347 ⟶ 4,568:
if {[lsearch $argv -p] >= 0} {parray D}
}
}</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
 
<langsyntaxhighlight lang="vbnet">Public Class DoubleLinkList(Of T)
Private m_Head As Node(Of T)
Private m_Tail As Node(Of T)
Line 4,478 ⟶ 4,699:
End Sub
 
End Class</langsyntaxhighlight>
 
=={{header|Wren}}==
{{libheader|Wren-llist}}
The DLinkedList class in the above module is a generic doubly-linked list and is implemented in such a way that circular loops are not possible. We therefore use it here.
<langsyntaxhighlight ecmascriptlang="wren">import "./llist" for DLinkedList
 
var dll = DLinkedList.new()
Line 4,489 ⟶ 4,710:
System.print(dll)
for (i in 1..3) dll.remove(i)
System.print(dll)</langsyntaxhighlight>
 
{{out}}
Line 4,496 ⟶ 4,717:
[]
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">
def \Node\ Prev, Data, Next; \Element (Node) definition
int Head(3), Tail(3); \Doubly linked list definition
[Head(Next):= Tail;
Tail(Prev):= Head;
]</syntaxhighlight>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">class Node{
fcn init(_value,_prev=Void,_next=Void)
{ var value=_value, prev=_prev, next=_next; }
Line 4,523 ⟶ 4,752:
}.fp(Ref(self),dir))
}
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">a:=Node("a");
a.append("c").append("d");
a.last().append("e");
a.last().first().append("b");
foreach n in (a){ print(n," ") } println();
foreach n in (a.last().walker(False)){ print(n," ") } println();</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits