566
社区成员
发帖
与我相关
我的任务
分享
创建linktable文件夹,在文件夹内创建linktable.go,代码如下:
package linktable
type LinkTable[T comparable] struct {
head *node[T]
tail *node[T]
count int
}
type node[T comparable] struct {
data T
prev *node[T]
next *node[T]
}
func New[T comparable]() *LinkTable[T] {
return &LinkTable[T]{nil, nil, 0}
}
func (t *LinkTable[T]) Append(data T) {
if t.head == nil {
t.head = &node[T]{data, nil, nil}
t.tail = t.head
} else {
t.tail.next = &node[T]{data, t.tail, nil}
t.tail = t.tail.next
}
t.count++
}
func (t *LinkTable[T]) RemoveTail() T {
if t.count == 0 {
panic("list empty")
}
removed := t.tail
t.tail = removed.prev
if removed.prev != nil {
removed.prev.next = nil
} else {
t.head = nil
}
t.count--
return removed.data
}
func (t *LinkTable[T]) Prepend(data T) {
newHead := &node[T]{data, nil, t.head}
if t.head != nil {
t.head.prev = newHead
t.head = newHead
} else {
t.head = newHead
t.tail = newHead
}
t.count++
}
func (t *LinkTable[T]) Len() int {
return t.count
}
func (t *LinkTable[T]) RemoveHead() T {
if t.count == 0 {
panic("list empty")
}
removed := t.head
t.head = removed.next
if removed.next != nil {
removed.next.prev = nil
} else {
t.head = nil
}
t.count--
return removed.data
}
func (t *LinkTable[T]) ToSlice() []T {
var result []T
cur := t.head
for {
if cur == nil {
break
}
result = append(result, cur.data)
cur = cur.next
}
return result
}
func (t *LinkTable[T]) Find(data T) int {
i := 0
cur := t.head
for {
if cur == nil {
break
}
if cur.data == data {
return i
}
cur = cur.next
i++
}
return -1
}
上述代码使用了Go新推出的泛型功能,实现了一个通用的双向链表。 具有在头部或尾部插入/删除数据的功能,还可以将链表内容转化为Go语言内置的slice。
设计程序库时,应该避免过多暴露内部实现细节,如此处的node结构体就是非公开的,head、tail指针也不对用户可见。
此外还应当对用户输入做好校验,如RemoveHead、RemoveTail方法就需要判断链表是否为空。
代码库:https://gitee.com/hamletive/linktable
作者:SA*****442