添加skiptable
This commit is contained in:
parent
9e4a26aac6
commit
58f3bda481
|
@ -0,0 +1,133 @@
|
||||||
|
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 // 上层已
|
||||||
|
|
Loading…
Reference in New Issue