跳表
package main
import (
"fmt"
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
type SkipList struct {
head *SkipListNode
maxLevel int
length int
}
type SkipListNode struct {
key int
value int
next []*SkipListNode
}
func NewSkipList() *SkipList {
return &SkipList{
head: &SkipListNode{
next: make([]*SkipListNode, 1),
},
maxLevel: 1,
length: 0,
}
}
func (s *SkipList) Insert(key int, value int) {
update := make([]*SkipListNode, s.maxLevel)
current := s.head
for i := s.maxLevel - 1; i >= 0; i-- {
for current.next[i] != nil && current.next[i].key < key {
current = current.next[i]
}
update[i] = current
}
current = current.next[0]
if current != nil && current.key == key {
current.value = value
return
}
level := randomLevel(s.maxLevel)
if level > s.maxLevel {
for i := s.maxLevel; i < level; i++ {
update = append(update, s.head)
}
s.maxLevel++
s.head.next = append(s.head.next, nil)
}
node := &SkipListNode{
key: key,
value: value,
next: make([]*SkipListNode, level),
}
for i := 0; i < level; i++ {
if i < len(update[i].next) {
node.next[i] = update[i].next[i]
update[i].next[i] = node
}
}
s.length++
}
func randomLevel(l int) int {
level := 1
for rand.Intn(2) == 0 {
level++
if level >= l+1 {
break
}
}
return level
}
func (s *SkipList) Delete(key int) {
update := make([]*SkipListNode, s.maxLevel)
current := s.head
for i := s.maxLevel - 1; i >= 0; i-- {
for current.next[i] != nil && current.next[i].key < key {
current = current.next[i]
}
update[i] = current
}
current = current.next[0]
if current != nil && current.key == key {
for i := 0; i < s.maxLevel; i++ {
if update[i].next[i] != current {
break
}
update[i].next[i] = current.next[i]
}
for s.maxLevel > 1 && s.head.next[s.maxLevel-1] == nil {
s.maxLevel--
}
s.length--
}
}
func (s *SkipList) Search(key int) int {
current := s.head
for i := s.maxLevel - 1; i >= 0; i-- {
for current.next[i] != nil && current.next[i].key < key {
current = current.next[i]
}
}
current = current.next[0]
if current != nil && current.key == key {
return current.value
}
return -1
}
func (s *SkipList) Print() {
for i := s.maxLevel - 1; i >= 0; i-- {
current := s.head
fmt.Printf("level %d: ", i)
for current.next[i] != nil {
current = current.next[i]
fmt.Printf("%d ", current.key)
}
fmt.Println()
}
}
func main() {
sl := NewSkipList()
for i := 0; i < 20; i++ {
sl.Insert(i, i+100)
}
sl.Print()
fmt.Printf("search: %d\n", sl.Search(5))
}