package main
import (
"bytes"
"fmt"
"sync"
)
var (
mu sync.Mutex
)
type Node struct {
p *Node
left *Node
right *Node
value interface{}
}
type List struct {
first *Node
last *Node
length uint64
}
func main() {
l := &List{}
fmt.Println(l.rpush("aa"))
fmt.Println(l.lpush("bb"))
fmt.Println(l.lpush("cc"))
fmt.Println(l.lpush("dd"))
fmt.Printf("List: %v \n", l)
fmt.Printf("contains: %v \n", l.contains("aa"))
fmt.Println(l.size())
fmt.Printf("List: %v \n", l)
fmt.Println(l.pop())
fmt.Println(l.pop())
fmt.Println(l.shift())
fmt.Printf("List: %v \n", l)
fmt.Println("–")
fmt.Println(l.first)
fmt.Println(l.last)
}
func (l *List) String() string {
node := l.first
if node == nil {
return ""
}
var b bytes.Buffer
for {
fmtS := " <-> %s"
if b.Len() == 0 {
fmtS = "%s"
}
_, err := fmt.Fprintf(&b, fmtS, node.value)
if err != nil {
return ""
}
node = node.right
if node == nil {
break
}
}
return b.String()
}
func (n *Node) String() string {
if n == nil {
return "nil"
}
var left = new(Node)
var right = new(Node)
left.value = "nil"
right.value = "nil"
if n.left != nil {
left = n.left
}
if n.right != nil {
right = n.right
}
return "Left: '" + (left.value).(string) + "' Right: '" + (right.value).(string) + "' Value: '" + (n.value).(string) + "'"
}
// first add
func (l *List) lpush(value interface{}) uint64 {
mu.Lock()
defer mu.Unlock()
f := l.first
node := &Node{
value: value,
right: f,
}
if f != nil {
f.left = node
} else {
l.last = node
}
l.first = node
l.length++
return l.length
}
// last add
func (l *List) rpush(value interface{}) uint64 {
mu.Lock()
defer mu.Unlock()
f := l.last
node := &Node{
value: value,
left: f,
}
if f != nil {
f.right = node
} else {
l.first = node
}
l.last = node
l.length++
return l.length
}
func (l *List) pop() *Node {
mu.Lock()
defer mu.Unlock()
last := l.last
if last == nil {
return nil
}
last2 := last.left // if nil
l.last = last2
if last2 != nil {
last2.right = nil
} else {
l.first = nil
}
l.length–
return last
}
func (l *List) shift() *Node {
mu.Lock()
defer mu.Unlock()
first := l.first
if first == nil {
return nil
}
first2 := first.right // if nil
l.first = first2
if first2 != nil {
first2.left = nil
} else {
l.last = nil
}
l.length–
return first
}
func (l *List) size() uint64 {
return l.length
}
func (l *List) contains(value interface{}) bool {
mu.Lock()
defer mu.Unlock()
f := l.first
if f == nil {
return false
}
for {
if f.value == value {
return true
}
if f.right == nil {
break
}
f = f.right
}
return false
}