Golang1.18泛型_LinkedList

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
}

posted @ 2022-04-20 17:25  月下繁星杨  阅读(172)  评论(0编辑  收藏  举报