Skiplist(跳表)

跳表Golang实现

package skiplist

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
)

type Node struct {
	Key     int
	Value   int
	Forward []*Node
}

func NewNode(level int, key int, value int) *Node {
	return &Node{
		Key:     key,
		Value:   value,
		Forward: make([]*Node, level),
	}
}

type SkipList struct {
	header *Node

	level    int
	maxLevel int
	size     int
}

func New(maxLevel int) *SkipList {
	return &SkipList{
		header:   NewNode(maxLevel, -1, -1),
		level:    0,
		maxLevel: maxLevel,
	}
}

func (s *SkipList) Search(key int) (int, bool) {
	updateList := s.GetUpdateList(key)
	n, ok := s.Find(updateList, key)
	if !ok {
		return 0, false
	}
	return n.Value, true
}

func (s *SkipList) Insert(key int, value int) {
	updateList := s.GetUpdateList(key)

	// 存在
	q, ok := s.Find(updateList, key)
	if ok && q.Value == value {
		return
	}

	k := s.Random()
	if k > s.maxLevel {
		k = s.maxLevel
	}
	for lv := s.level; lv < k; lv++ {
		updateList[lv] = s.header
		s.level++
	}

	q = NewNode(k, key, value)

	for i := 0; i < k; i++ {
		q.Forward[i] = updateList[i].Forward[i]
		updateList[i].Forward[i] = q
	}
	s.size++
}

func (s *SkipList) Remove(key int) {
	updateList := s.GetUpdateList(key)
	q, ok := s.Find(updateList, key)
	if !ok {
		return
	}

	for i := 0; i < s.level; i++ {
		if updateList[i].Forward[i] == q {
			updateList[i].Forward[i] = q.Forward[i]
		}
	}
	for i := s.level - 1; i >= 0; i-- {
		if s.header.Forward[i] == nil {
			s.level--
		}
		i--
	}
	s.size--
}

func (s *SkipList) GetUpdateList(key int) (updateList []*Node) {
	updateList = make([]*Node, s.maxLevel)
	i := s.level - 1
	for i >= 0 {
		q := s.header
		for q.Forward[i] != nil && q.Forward[i].Key < key {
			q = q.Forward[i]
		}
		updateList[i] = q
		i--
	}

	return updateList
}

func (s *SkipList) Find(updateList []*Node, key int) (*Node, bool) {
	if len(updateList) == 0 {
		updateList = s.GetUpdateList(key)
	}

	if len(updateList) > 0 {
		if updateList[0] != nil && len(updateList[0].Forward) > 0 && updateList[0].Forward[0] != nil && updateList[0].Forward[0].Key == key {
			return updateList[0].Forward[0], true
		}
	}

	return nil, false
}
func (s *SkipList) Random() int {
	level := 1
	for rand.Intn(10) < 5 && s.maxLevel > level {
		level++
	}

	return level
}

func (s *SkipList) Len() int {
	return s.size
}

func (s *SkipList) Traval() {
	for i := s.level - 1; i >= 0; i-- {
		var ss []string
		for q := s.header; q != nil; q = q.Forward[i] {
			ss = append(ss, strconv.Itoa(q.Key))
		}
		fmt.Println("层数: ", i, strings.Join(ss, "->"))
	}
}