Skip to content

Commit 46f4e3c

Browse files
committed
update golang linkedlist
1 parent ee4ba26 commit 46f4e3c

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

go/linkedlist/linkedlist.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package linkedlist
2+
3+
type Lister interface {
4+
Clear()
5+
Len() int
6+
Front() *Element
7+
Back() *Element
8+
Remove(e *Element) interface{}
9+
PushFront(v interface{}) *Element
10+
PushBack(v interface{}) *Element
11+
InsertBefore(v interface{}, mark *Element) *Element
12+
InsertAfter(v interface{}, mark *Element) *Element
13+
MoveBefore(e, mark *Element)
14+
MoveAfter(e, mark *Element)
15+
}
16+
17+
type Element struct {
18+
prev, next *Element
19+
list *List
20+
Value interface{}
21+
}
22+
23+
func (e *Element) Next() *Element {
24+
if n := e.next; n != nil && n != &e.list.root {
25+
return n
26+
}
27+
return nil
28+
}
29+
30+
func (e *Element) Prev() *Element {
31+
if p := e.prev; p != nil && p != &e.list.root {
32+
return p
33+
}
34+
return nil
35+
}
36+
37+
type List struct {
38+
root Element
39+
len int
40+
}
41+
42+
func New() *List {
43+
l := new(List)
44+
l.Clear()
45+
return l
46+
}
47+
48+
func (l *List) Clear() {
49+
if firstElem := l.root.next; firstElem != nil && firstElem.list == l {
50+
firstElem.prev = nil
51+
}
52+
if lastElem := l.root.prev; lastElem != nil && lastElem.list == l {
53+
lastElem.next = nil
54+
}
55+
l.root.next = &l.root
56+
l.root.prev = &l.root
57+
l.len = 0
58+
}
59+
60+
func (l *List) Len() int {
61+
return l.len
62+
}
63+
64+
func (l *List) Front() *Element {
65+
if l.len == 0 {
66+
return nil
67+
}
68+
return l.root.next
69+
}
70+
71+
func (l *List) Back() *Element {
72+
if l.len == 0 {
73+
return nil
74+
}
75+
return l.root.prev
76+
}
77+
78+
func (l *List) remove(e *Element) *Element {
79+
e.prev.next = e.next
80+
e.next.prev = e.prev
81+
e.prev = nil
82+
e.next = nil
83+
e.list = nil
84+
l.len--
85+
return e
86+
}
87+
88+
func (l *List) Remove(e *Element) interface{} {
89+
if e.list == l {
90+
l.remove(e)
91+
}
92+
return e.Value
93+
}
94+
95+
func (l *List) insert(e, at *Element) *Element {
96+
n := at.next
97+
at.next = e
98+
e.prev = at
99+
e.next = n
100+
n.prev = e
101+
e.list = l
102+
l.len++
103+
return e
104+
}
105+
106+
func (l *List) insertValue(v interface{}, at *Element) *Element {
107+
return l.insert(&Element{Value: v}, at)
108+
}
109+
110+
func (l *List) PushFront(v interface{}) *Element {
111+
return l.insertValue(v, &l.root)
112+
}
113+
114+
func (l *List) PushBack(v interface{}) *Element {
115+
return l.insertValue(v, l.root.prev)
116+
}
117+
118+
func (l *List) InsertBefore(v interface{}, mark *Element) *Element {
119+
if mark.list != l {
120+
return nil
121+
}
122+
return l.insertValue(v, mark.prev)
123+
}
124+
125+
func (l *List) InsertAfter(v interface{}, mark *Element) *Element {
126+
if mark.list != l {
127+
return nil
128+
}
129+
return l.insertValue(v, mark)
130+
}
131+
132+
func (l *List) MoveBefore(e, mark *Element) {
133+
if e.list != l || mark.list != l || e == mark {
134+
return
135+
}
136+
l.insert(l.remove(e), mark.prev)
137+
}
138+
139+
func (l *List) MoveAfter(e, mark *Element) {
140+
if e.list != l || mark.list != l || e == mark {
141+
return
142+
}
143+
l.insert(l.remove(e), mark)
144+
}

go/linkedlist/linkedlist_test.go

Whitespace-only changes.

0 commit comments

Comments
 (0)