数据结构
04-静态链表实现
静态链表
线性表的静态链表:使用一维数组来描述线性链表,同样每个数组的元素包含数据域、指针域,不同的是指针域不再是元素的地址值, 而是通过存储指向的目标元素在数组中的索引来实现。
静态链表对线性表的实现
依然采取类似链表小节中的链表对线性表的实现所述的链表结构进行组织。
类型的定义
表示结点的结构体
type StaticLinkedListNode struct {
Next int
Data any
isHead bool
}
表示链表的结构体
type StaticLinkedList struct {
head []*StaticLinkedListNode
length int
capacity int
//isCircular bool
gcPool map[int]any // store deleted element index, and reuse it in InsertByIndex func
}
对线性表接口的实现
前面列出了线性表的基础操作,这里会对其一一进行实现,但是在实现任何一个方法前,我 们需要先实现其初始化方法。
0. NewSingleLinkedList
// 初始化
func NewStaticLinkedList(cap int) (l *StaticLinkedList) {
list := new(StaticLinkedList)
list.capacity = cap
list.gcPool = make(map[int]any)
list.head = make([]*StaticLinkedListNode, 1, cap+1)
list.head[0] = &StaticLinkedListNode{
Next: 0,
isHead: true,
}
return list
}
1. ClearList
// 清空线性表中的数据
func NewStaticLinkedList(cap int) (l *StaticLinkedList) {
list := new(StaticLinkedList)
list.capacity = cap
list.gcPool = make(map[int]any)
list.head = make([]*StaticLinkedListNode, 1, cap+1)
list.head[0] = &StaticLinkedListNode{
Next: 0,
isHead: true,
}
return list
}
2. IsEmpty
func (s *StaticLinkedList) IsEmpty() bool {
return s.length == 0
}
3. GetLength
func (s *StaticLinkedList) GetLength() int {
return s.length
}
4. GetElementByIndex
// 获取线性表中位于指定索引的元素
func (s *StaticLinkedList) GetElementByIndex(index int) (any, error) {
if index >= s.length || index < 0 {
return nil, fmt.Errorf("index out of range")
}
var curr = 0
for i := 0; i <= index; i++ {
curr = s.head[curr].Next
}
return s.head[curr].Data, nil
}
5. GetElementIndexByValue
// 获取线性表中与指定值相等元素的索引
func (s *StaticLinkedList) GetElementIndexByValue(element any) (int, error) {
var curr = s.head[0].Next
for i := 0; i < s.length; i++ {
if s.head[curr].Data == element {
return i, nil
}
curr = s.head[curr].Next
}
return 0, fmt.Errorf("can't find element %s in data", element)
}
6. GetPriorElement
// 获取线性表中与指定值相等元素的前一个元素
func (s *StaticLinkedList) GetPriorElement(element any) (any, error) {
var previous, current = 0, 0
for i := 0; i < s.length+1; i++ {
if i == 0 { // skip head node
previous = current
current = s.head[current].Next
continue
}
if s.head[current].Data == element {
if i == 1 {
return 0, fmt.Errorf("element %s has been found, but it's already the first element", element)
}
return s.head[previous].Data, nil
}
previous = current
current = s.head[current].Next
}
return 0, fmt.Errorf("can't find element %s in data", element)
}
7. GetNextElement
// 获取线性表中与指定值相等元素的后一个元素
func (s *StaticLinkedList) GetNextElement(element any) (any, error) {
var current = 0
for i := 0; i < s.length+1; i++ {
if i == 0 { // skip head node
current = s.head[current].Next
continue
}
if s.head[current].Data == element {
if i == s.length {
return 0, fmt.Errorf("element %s has been found, but it's already the last element", element)
}
nextIndex := s.head[current].Next
return s.head[nextIndex].Data, nil
}
current = s.head[current].Next
}
return 0, fmt.Errorf("can't find element %s in data", element)
}
8. InsertByIndex
// 在线性表中指定索引处插入元素
// InsertByIndex you can insert element into the list, between head and tail, or you will get over range error
func (s *StaticLinkedList) InsertByIndex(index int, element any) error {
if index >= s.length+1 || index < 0 {
return fmt.Errorf("index is out of range")
}
// if new length great than cap, just return err
if s.length+1 > s.capacity {
return fmt.Errorf("new length can't longer than capacity")
}
var previous = 0
var curr = 0
for i := 0; i <= index; i++ {
previous = curr
curr = s.head[curr].Next
}
node := &StaticLinkedListNode{
Data: element,
}
gcIndex := -1
if len(s.gcPool) > 0 {
for gcIndex = range s.gcPool {
break
}
}
realIndex := s.length + 1 // default there isn't gc element
if gcIndex >= 0 {
realIndex = gcIndex // There is gc element, set to real index
s.head[gcIndex] = node
delete(s.gcPool, gcIndex)
} else {
s.head = append(s.head, node) // There isn't gc element
}
s.head[previous].Next = realIndex
s.head[realIndex].Next = curr
s.length += 1
return nil
}
9. DeleteByIndex
// 获在线性表中指定索引处删除元素
// DeleteByIndex you can delete element by index, between head and tail, or you will get over range error
func (s *StaticLinkedList) DeleteByIndex(index int) (deletedElement any, err error) {
if index >= s.length || index < 0 {
return nil, fmt.Errorf("index is out of range")
}
var previous, curr = 0, 0
for i := 0; i <= index; i++ {
previous = curr
curr = s.head[curr].Next
}
deletedElement = s.head[curr].Data
s.gcPool[curr] = deletedElement
s.head[previous].Next = s.head[curr].Next
s.length -= 1
return deletedElement, nil
}
10. Traverse
// 遍历打印所有元素
func (s *StaticLinkedList) Traverse(f func(data any)) {
current := s.head[0].Next
for i := 0; i < s.length; i++ {
f(s.head[current].Data)
current = s.head[current].Next
}
}
其他同类文章
DATA-STRUCTURE · CHAPTER02
data structure chapter02
