LinkedList
- 与java的api基本保持一致,也可以使用泛型接口,但最新版的Goland的最新版本对泛型接口的支持有bug,编辑器会爆红,但代码可以正常运行,可以自行扩展接口,实现栈和队列等结构。
使用示例
func main() {
p := &Person{name: "java"}
p2 := &Person{name: "C++"}
l := LinkedList.New[*Person]()
l.Add(p)
l.Add(p2)
fmt.Println(l.Size())
fmt.Println(l.GetFirst())
l.ForEach(func(p *Person) {
fmt.Println(p)
})
}
type Person struct {
name string
}
package LinkedList
import (
"reflect"
)
const NoSuchElementException = "No Such Element Exception"
type node[T any] struct {
elem *T
next *node[T]
prev *node[T]
}
type linkedList[T any] struct {
first *node[T]
last *node[T]
size uint
}
func New[T any]() *linkedList[T] {
return &linkedList[T]{first: nil, last: nil, size: 0}
}
func (list *linkedList[T]) GetFirst() T {
if list.first == nil {
panic("No Sucn ElementException")
}
return *list.first.elem
}
func (list *linkedList[T]) GetLast() T {
l := list.last
if l == nil {
panic("No Sucn ElementException")
}
return *l.elem
}
// RemoveFirst 移除链表头部元素
func (list *linkedList[T]) RemoveFirst() T {
node := list.first
if node == nil {
panic(NoSuchElementException)
}
return list.removeFirst(node)
}
// RemoveLeast 移除链表尾部元素
func (list *linkedList[T]) RemoveLeast() T {
node := list.last
if node == nil {
panic(NoSuchElementException)
}
return list.RemoveLeast()
}
// AddFirst 在链表头部添加元素
func (list *linkedList[T]) AddFirst(ele T) {
list.insertFirst(ele)
}
// AddLeast 在链表尾部添加元素
func (list *linkedList[T]) AddLeast(ele T) {
list.insertLast(ele)
}
// IndexOf 返回节点在链表中的索引,从first开始查找,如果找不到返回-1
func (list *linkedList[T]) IndexOf(ele T) int {
index := 0
first := list.first
for first != nil {
b := equals(first.elem, ele)
if b {
return index
} else {
first = first.next
index++
}
}
return -1
}
// LastIndexOf 返回节点在链表中的索引,从last开始查找,如果找不到返回-1
func (list *linkedList[T]) LastIndexOf(ele T) int {
last := list.last
index := list.size
for list != nil {
b := equals(last.elem, ele)
if b {
return int(index)
} else {
last = last.prev
index++
}
}
return -1
}
func (list *linkedList[T]) Peek() T {
node := list.first
return *node.elem
}
func (list *linkedList[T]) Element() T {
return list.GetFirst()
}
func (list *linkedList[T]) Poll() T {
node := list.first
return list.removeFirst(node)
}
func (list *linkedList[T]) Remove(ele T) bool {
first := list.first
for first != nil {
b := equals(first.elem, ele)
if b {
list.remove(first)
return true
} else {
first = first.next
}
}
return false
}
func (list *linkedList[T]) Add(ele T) bool {
list.insertLast(ele)
return true
}
func (list *linkedList[T]) Offer(ele T) bool {
return list.Add(ele)
}
func (list *linkedList[T]) OfferFirst(ele T) bool {
list.insertFirst(ele)
return true
}
func (list *linkedList[T]) OfferLast(ele T) bool {
list.insertLast(ele)
return true
}
func (list *linkedList[T]) PeekFirst() T {
return *list.first.elem
}
func (list *linkedList[T]) PeekLast() T {
return *list.last.elem
}
func (list *linkedList[T]) PollFirst() T {
first := list.first
return list.removeFirst(first)
}
func (list *linkedList[T]) PollLast() T {
last := list.last
return list.removeLast(last)
}
func (list *linkedList[T]) Push(ele T) {
list.insertFirst(ele)
}
func (list *linkedList[T]) Pop() T {
return list.RemoveFirst()
}
func (list *linkedList[T]) RemoveFirstOccurrence(ele T) bool {
return list.Remove(ele)
}
func (list *linkedList[T]) RemoveLastOccurrence(ele T) bool {
last := list.last
for last != nil {
b := equals(last.elem, ele)
if b {
list.remove(last)
return true
}
}
return false
}
func (list *linkedList[T]) ForEach(f func(ele T)) {
first := list.first
for first != nil {
f(*first.elem)
first = first.next
}
}
func (list *linkedList[T]) ToArray() []T {
arr := make([]T, list.size)
i := 0
first := list.first
for first != nil {
arr[i] = *first.elem
i++
first = first.next
}
return arr
}
func (list *linkedList[T]) removeFirst(first *node[T]) T {
ele := first.elem
nxt := first.next
first.elem = nil
first.next = nil
list.first = nxt
if nxt == nil {
list.last = nil
} else {
nxt.prev = nil
}
list.size--
return *ele
}
func (list *linkedList[T]) removeLast(last *node[T]) T {
ele := last.elem
prev := last.prev
last.elem = nil
last.prev = nil
list.last = prev
if prev == nil {
list.first = nil
} else {
prev.next = nil
}
list.size--
return *ele
}
func (list *linkedList[T]) remove(node *node[T]) T {
ele := node.elem
next := node.next
prev := node.prev
if prev == nil {
list.first = next
} else {
prev.next = next
node.prev = nil
}
if next == nil {
list.last = prev
} else {
next.prev = prev
node.next = nil
}
node.elem = nil
list.size--
return *ele
}
func (list *linkedList[T]) insertLast(e T) {
last := list.last
node := new(node[T])
node.elem = &e
node.prev = last
if last == nil {
list.first = node
} else {
last.next = node
}
list.size++
}
func (list *linkedList[T]) insertFirst(e T) {
first := list.first
node := &node[T]{
elem: &e,
next: first,
prev: nil,
}
if first == nil {
list.first = node
} else {
first.prev = node
}
list.size++
}
func (list *linkedList[T]) Size() int {
return int(list.size)
}
func (list *linkedList[T]) insertBefore(e T, bef *node[T]) {
if bef == nil {
panic(NoSuchElementException + ": before node")
}
node := &node[T]{
elem: &e,
next: nil,
prev: nil,
}
if bef.prev == nil {
list.insertFirst(e)
} else {
bef.prev.next = node
bef.prev = node
node.next = bef
node.prev = bef.prev
}
list.size++
}
func equals(a interface{}, b interface{}) bool {
if e, ok := a.(compare); ok {
return e.Equal(b)
} else {
return reflect.DeepEqual(a, b)
}
}
type compare interface {
Equal(object interface{}) bool
}