[Golang扩展]手写Golang跳表
package SkipList
import (
"fmt"
"math/rand"
)
const MaxLevel = 10
type Node struct {
score int
value string
next []*Node
}
func NewNode(score int, value string, level int) *Node {
node := Node{score: score, value: value, next: make([]*Node, level)}
return &node
}
type SkipList struct {
level int
len int
head Node
}
func NewSkipList() *SkipList {
sl := SkipList{}
sl.level = 1
sl.head.next = make([]*Node, MaxLevel)
return &sl
}
func (sl *SkipList) Show() {
fmt.Println("show skipList ----------------")
for i := sl.level - 1; i >= 0; i-- {
fmt.Printf("level %d: ", i+1)
cur := sl.head.next[i]
for cur != nil {
fmt.Print(cur.score, cur.value)
cur = cur.next[i]
if cur != nil {
fmt.Print("->")
}
}
fmt.Println()
}
}
func (sl *SkipList) Insert(score int, value string) {
fmt.Println("插入节点", score, value)
prev := &sl.head
breakPoints := make([]*Node, sl.level)
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
if cur.score == score {
cur.value = value
fmt.Println("有重复score,直接覆盖", score, value)
return
} else if cur.score > score {
break
} else {
prev = cur
}
}
breakPoints[i] = prev
}
// 生成新结点层级
randomLevel := MaxLevel
randomNumber := rand.Intn(1 << MaxLevel)
for i := 1; i <= MaxLevel; i++ {
if randomNumber >= 1<<(MaxLevel-i) {
randomLevel = i
break
}
}
if randomLevel > sl.level {
randomLevel = sl.level + 1
}
fmt.Println("新节点层级 = ", randomLevel)
newNode := NewNode(score, value, randomLevel)
if randomLevel > sl.level {
for i := 0; i < sl.level; i++ {
newNode.next[i] = breakPoints[i].next[i]
breakPoints[i].next[i] = newNode
}
sl.head.next[randomLevel-1] = newNode
sl.level += 1
} else {
for i := 0; i < randomLevel; i++ {
newNode.next[i] = breakPoints[i].next[i]
breakPoints[i].next[i] = newNode
}
}
}
func (sl *SkipList) FindByScore(score int) string {
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
if cur.score == score {
return cur.value
} else if cur.score > score {
break
} else {
prev = cur
}
}
}
return ""
}
func (sl *SkipList) FindByValue(value string) int {
for cur := sl.head.next[0]; cur != nil; cur = cur.next[0] {
if cur.value == value {
return cur.score
}
}
return -1
}
func (sl *SkipList) RemoveByScore(score int) {
fmt.Println("删除节点score", score)
deletePoints := make([]*Node, sl.level)
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
if cur.score < score {
prev = cur
}
}
deletePoints[i] = prev
}
for i := 0; i < sl.level; i++ {
if deletePoints[i].next[i] != nil && deletePoints[i].next[i].score == score {
deletePoints[i].next[i] = deletePoints[i].next[i].next[i]
}
}
}
func (sl *SkipList) RemoveByValue(value string) {
deletePoints := make([]*Node, sl.level)
for i := sl.level - 1; i >= 0; i-- {
for cur := sl.head.next[i]; cur.next[i] != nil; cur = cur.next[i] {
if cur.next[i].value == value {
deletePoints[i] = cur
}
}
}
for i := 0; i < sl.level; i++ {
if deletePoints[i] != nil {
deletePoints[i].next[i] = deletePoints[i].next[i].next[i]
}
}
}
func (sl *SkipList) RangeSearch(start, end int) []string {
if start > end {
fmt.Println("非法范围,起点大于终点")
return []string{}
}
prev := &sl.head
for i := sl.level - 1; i >= 0; i-- {
for cur := prev.next[i]; cur != nil; cur = cur.next[i] {
if cur.score < start {
prev = cur
}
}
}
var res []string
for cur := prev.next[0]; cur != nil && cur.score <= end; cur = cur.next[0] {
res = append(res, cur.value)
}
return res
}
Test
func TestNewSkipList(t *testing.T) {
sl := SkipList.NewSkipList()
sl.Insert(4, "D")
sl.Insert(5, "E")
sl.Insert(6, "F")
sl.Insert(1, "A")
sl.Insert(2, "B")
sl.Insert(3, "C")
sl.Show()
fmt.Println(sl.RangeSearch(5, 5))
}