From 58f3bda4817a486f339ec90c7bf090cbeafcf137 Mon Sep 17 00:00:00 2001 From: kingecg Date: Mon, 24 Feb 2025 00:39:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0skiptable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skiptable.go | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 skiptable.go diff --git a/skiptable.go b/skiptable.go new file mode 100644 index 0000000..b6f6d3d --- /dev/null +++ b/skiptable.go @@ -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 // 上层已 +   \ No newline at end of file