1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package list implements a doubly linked list.
7 // To iterate over a list (where l is a *List):
8 // for e := l.Front(); e != nil; e = e.Next() {
9 // // do something with e.Value
14 // Element is an element of a linked list.
16 // Next and previous pointers in the doubly-linked list of elements.
17 // To simplify the implementation, internally a list l is implemented
18 // as a ring, such that &l.root is both the next element of the last
19 // list element (l.Back()) and the previous element of the first list
20 // element (l.Front()).
23 // The list to which this element belongs.
26 // The value stored with this element.
30 // Next returns the next list element or nil.
31 func (e
*Element
) Next() *Element
{
32 if p
:= e
.next
; e
.list
!= nil && p
!= &e
.list
.root
{
38 // Prev returns the previous list element or nil.
39 func (e
*Element
) Prev() *Element
{
40 if p
:= e
.prev
; e
.list
!= nil && p
!= &e
.list
.root
{
46 // List represents a doubly linked list.
47 // The zero value for List is an empty list ready to use.
49 root Element
// sentinel list element, only &root, root.prev, and root.next are used
50 len int // current list length excluding (this) sentinel element
53 // Init initializes or clears list l.
54 func (l
*List
) Init() *List
{
61 // New returns an initialized list.
62 func New() *List
{ return new(List
).Init() }
64 // Len returns the number of elements of list l.
65 // The complexity is O(1).
66 func (l
*List
) Len() int { return l
.len }
68 // Front returns the first element of list l or nil.
69 func (l
*List
) Front() *Element
{
76 // Back returns the last element of list l or nil.
77 func (l
*List
) Back() *Element
{
84 // lazyInit lazily initializes a zero List value.
85 func (l
*List
) lazyInit() {
86 if l
.root
.next
== nil {
91 // insert inserts e after at, increments l.len, and returns e.
92 func (l
*List
) insert(e
, at
*Element
) *Element
{
103 // insertValue is a convenience wrapper for insert(&Element{Value: v}, at).
104 func (l
*List
) insertValue(v
interface{}, at
*Element
) *Element
{
105 return l
.insert(&Element
{Value
: v
}, at
)
108 // remove removes e from its list, decrements l.len, and returns e.
109 func (l
*List
) remove(e
*Element
) *Element
{
112 e
.next
= nil // avoid memory leaks
113 e
.prev
= nil // avoid memory leaks
119 // Remove removes e from l if e is an element of list l.
120 // It returns the element value e.Value.
121 func (l
*List
) Remove(e
*Element
) interface{} {
123 // if e.list == l, l must have been initialized when e was inserted
124 // in l or l == nil (e is a zero Element) and l.remove will crash
130 // PushFront inserts a new element e with value v at the front of list l and returns e.
131 func (l
*List
) PushFront(v
interface{}) *Element
{
133 return l
.insertValue(v
, &l
.root
)
136 // PushBack inserts a new element e with value v at the back of list l and returns e.
137 func (l
*List
) PushBack(v
interface{}) *Element
{
139 return l
.insertValue(v
, l
.root
.prev
)
142 // InsertBefore inserts a new element e with value v immediately before mark and returns e.
143 // If mark is not an element of l, the list is not modified.
144 func (l
*List
) InsertBefore(v
interface{}, mark
*Element
) *Element
{
148 // see comment in List.Remove about initialization of l
149 return l
.insertValue(v
, mark
.prev
)
152 // InsertAfter inserts a new element e with value v immediately after mark and returns e.
153 // If mark is not an element of l, the list is not modified.
154 func (l
*List
) InsertAfter(v
interface{}, mark
*Element
) *Element
{
158 // see comment in List.Remove about initialization of l
159 return l
.insertValue(v
, mark
)
162 // MoveToFront moves element e to the front of list l.
163 // If e is not an element of l, the list is not modified.
164 func (l
*List
) MoveToFront(e
*Element
) {
165 if e
.list
!= l || l
.root
.next
== e
{
168 // see comment in List.Remove about initialization of l
169 l
.insert(l
.remove(e
), &l
.root
)
172 // MoveToBack moves element e to the back of list l.
173 // If e is not an element of l, the list is not modified.
174 func (l
*List
) MoveToBack(e
*Element
) {
175 if e
.list
!= l || l
.root
.prev
== e
{
178 // see comment in List.Remove about initialization of l
179 l
.insert(l
.remove(e
), l
.root
.prev
)
182 // MoveBefore moves element e to its new position before mark.
183 // If e is not an element of l, or e == mark, the list is not modified.
184 func (l
*List
) MoveBefore(e
, mark
*Element
) {
185 if e
.list
!= l || e
== mark
{
188 l
.insert(l
.remove(e
), mark
.prev
)
191 // MoveAfter moves element e to its new position after mark.
192 // If e is not an element of l, or e == mark, the list is not modified.
193 func (l
*List
) MoveAfter(e
, mark
*Element
) {
194 if e
.list
!= l || e
== mark
{
197 l
.insert(l
.remove(e
), mark
)
200 // PushBackList inserts a copy of an other list at the back of list l.
201 // The lists l and other may be the same.
202 func (l
*List
) PushBackList(other
*List
) {
204 for i
, e
:= other
.Len(), other
.Front(); i
> 0; i
, e
= i
-1, e
.Next() {
205 l
.insertValue(e
.Value
, l
.root
.prev
)
209 // PushFrontList inserts a copy of an other list at the front of list l.
210 // The lists l and other may be the same.
211 func (l
*List
) PushFrontList(other
*List
) {
213 for i
, e
:= other
.Len(), other
.Back(); i
> 0; i
, e
= i
-1, e
.Prev() {
214 l
.insertValue(e
.Value
, &l
.root
)