tests/weghting_n_cutting_the_tree/dll/dll.go

102 lines
2.0 KiB
Go

package dll
type ListInterface interface {
Len() int // длина списка
Front() *ListItem // первый Item
Back() *ListItem // последний Item
PushFront(v interface{}) *ListItem // добавить значение в начало
PushBack(v interface{}) *ListItem // добавить значение в конец
Remove(i *ListItem) // удалить элемент
MoveToFront(i *ListItem) // переместить элемент в начало
}
type ListItem struct {
Value interface{} // значение
Next *ListItem // следующий элемент
Prev *ListItem // предыдущий элемент
}
type List struct {
Info ListItem
len int
}
func NewList() *List {
return &List{len: 0}
}
func (l *List) Len() int {
return l.len
}
func (l *List) Front() *ListItem {
return l.Info.Next
}
func (l *List) Back() *ListItem {
return l.Info.Prev
}
func (l *List) PushFront(v interface{}) *ListItem {
e := &ListItem{Value: v}
if l.len != 0 {
e.Prev = l.Info.Next
l.Info.Next.Next = e
} else {
l.Info.Prev = e
}
l.Info.Next = e
l.len++
return e
}
func (l *List) PushBack(v interface{}) *ListItem {
e := &ListItem{Value: v}
if l.len != 0 {
e.Next = l.Info.Prev
l.Info.Prev.Prev = e
} else {
l.Info.Next = e
}
l.Info.Prev = e
l.len++
return e
}
func (l *List) Remove(i *ListItem) {
if i.Prev == nil {
i.Prev = &ListItem{}
l.Info.Prev = i.Next
}
if i.Next == nil {
i.Next = &ListItem{}
l.Info.Next = i.Prev
}
i.Prev.Next = i.Next
i.Next.Prev = i.Prev
if l.Len() > 1 {
l.Info.Next.Next = nil
l.Info.Prev.Prev = nil
} else {
l.Info = ListItem{}
}
l.len--
}
func (l *List) MoveToFront(i *ListItem) {
if l.Info.Next == i {
return
}
if i.Prev != nil {
i.Prev.Next = i.Next
i.Next.Prev = i.Prev
} else {
i.Next.Prev = i.Prev
l.Info.Prev = i.Next
}
i.Prev = l.Front()
l.Front().Next = i
i.Next = nil
l.Info.Next = i
}