133 lines
26 KiB
Go
133 lines
26 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"math/rand"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
maxLevel = 32 // 最大层数
|
||
probability = 0.5 // 层数生成概率因子
|
||
)
|
||
|
||
// SkipNode 跳表节点结构
|
||
type SkipNode struct {
|
||
key int
|
||
value interface{}
|
||
forward []*SkipNode // 各层的前进指针
|
||
}
|
||
|
||
// NewSkipNode 创建新节点
|
||
func NewSkipNode(key int, value interface{}, level int) *SkipNode {
|
||
return &SkipNode{
|
||
key: key,
|
||
value: value,
|
||
forward: make([]*SkipNode, level),
|
||
}
|
||
}
|
||
|
||
// SkipList 跳表结构
|
||
type SkipList struct {
|
||
header *SkipNode // 头节点
|
||
level int // 当前最大层数
|
||
randSrc rand.Source // 随机数源
|
||
}
|
||
|
||
// NewSkipList 初始化跳表
|
||
func NewSkipList() *SkipList {
|
||
return &SkipList{
|
||
header: NewSkipNode(0, nil, maxLevel),
|
||
level: 1,
|
||
randSrc: rand.NewSource(time.Now().UnixNano()),
|
||
}
|
||
}
|
||
|
||
// randomLevel 生成随机层数 (抛硬币法)
|
||
func (sl *SkipList) randomLevel() int {
|
||
level := 1
|
||
for ; level < maxLevel && sl.randSrc.Int63()&0xFFFF < int64(probability*0xFFFF); level++ {
|
||
}
|
||
return level
|
||
}
|
||
|
||
// Search 查找键对应的值
|
||
func (sl *SkipList) Search(key int) (interface{}, bool) {
|
||
current := sl.header
|
||
// 从最高层开始查找
|
||
for i := sl.level - 1; i >= 0; i-- {
|
||
// 在当前层向右移动,直到找到大于等于key的节点
|
||
for current.forward[i] != nil && current.forward[i].key < key {
|
||
current = current.forward[i]
|
||
}
|
||
}
|
||
// 移动到最底层(0层)的下一个节点
|
||
current = current.forward[0]
|
||
if current != nil && current.key == key {
|
||
return current.value, true
|
||
}
|
||
return nil, false
|
||
}
|
||
|
||
// Insert 插入键值对
|
||
func (sl *SkipList) Insert(key int, value interface{}) {
|
||
update := make([]*SkipNode, maxLevel) // 各层需要更新的前驱节点
|
||
current := sl.header
|
||
|
||
// 1. 查找各层的前驱节点
|
||
for i := sl.level - 1; i >= 0; i-- {
|
||
for current.forward[i] != nil && current.forward[i].key < key {
|
||
current = current.forward[i]
|
||
}
|
||
update[i] = current
|
||
}
|
||
|
||
// 2. 检查是否已存在相同key
|
||
current = current.forward[0]
|
||
if current != nil && current.key == key {
|
||
current.value = value // 更新值
|
||
return
|
||
}
|
||
|
||
// 3. 生成新节点的随机层数
|
||
newLevel := sl.randomLevel()
|
||
if newLevel > sl.level {
|
||
// 补充高层的前驱节点为header
|
||
for i := sl.level; i < newLevel; i++ {
|
||
update[i] = sl.header
|
||
}
|
||
sl.level = newLevel
|
||
}
|
||
|
||
// 4. 创建新节点并插入各层
|
||
newNode := NewSkipNode(key, value, newLevel)
|
||
for i := 0; i < newLevel; i++ {
|
||
newNode.forward[i] = update[i].forward[i]
|
||
update[i].forward[i] = newNode
|
||
}
|
||
}
|
||
|
||
// Delete 删除指定键的节点
|
||
func (sl *SkipList) Delete(key int) bool {
|
||
update := make([]*SkipNode, maxLevel)
|
||
current := sl.header
|
||
|
||
// 1. 查找各层的前驱节点
|
||
for i := sl.level - 1; i >= 0; i-- {
|
||
for current.forward[i] != nil && current.forward[i].key < key {
|
||
current = current.forward[i]
|
||
}
|
||
update[i] = current
|
||
}
|
||
|
||
// 2. 定位到目标节点
|
||
current = current.forward[0]
|
||
if current == nil || current.key != key {
|
||
return false // 未找到
|
||
}
|
||
|
||
// 3. 从各层链表中移除
|
||
for i := 0; i < sl.level; i++ {
|
||
if update[i].forward[i] != current {
|
||
break // 上层已
|
||
|