Go language jump table (SkipList)

Source: Internet
Author: User

Go language jump table (SkipList)

The Skip table (skiplist) is a core data structure in redis/levelDB. I simply and rudely implemented it using Golang.

In my simple understanding, a common linked list converts a layer into multiple layers through Random_level () during insert,

The smaller the data, the larger the span. Search from top to bottom and use space for time.

Write down the test code:

 

package mainimport ("fmt"//"github.com/xclpkg/algorithm""math/rand")func main() {slt := NewSkipList()for i := 100; i > 0; i-- {slt.Insert(i)}slt.PrintSkipList()slt.Search(20)slt.Search(36)slt.Search(93)slt.Delete(55)slt.PrintSkipList()}const SKIPLIST_MAXLEVEL = 8 //32const SKIPLIST_P = 4type SkipList struct {Header []ListLevel  int}func NewSkipList() *SkipList {return &SkipList{Level: 1, Header: make([]List, SKIPLIST_MAXLEVEL)}}func (skipList *SkipList) Insert(key int) {update := make(map[int]*Node)for i := len(skipList.Header) - 1; i >= 0; i-- {if skipList.Header[i].Len() > 0 {for e := skipList.Header[i].Front(); e != nil; e = e.Next() {if e.Value.(int) >= key {update[i] = ebreak}}} //Heaer[lv].List} //Header Levellevel := skipList.Random_level()if level > skipList.Level {skipList.Level = level}for i := 0; i < level; i++ {if v, ok := update[i]; ok {skipList.Header[i].InsertBefore(key, v)} else {skipList.Header[i].PushBack(key)}}}func (skipList *SkipList) Search(key int) *Node {for i := len(skipList.Header) - 1; i >= 0; i-- {if skipList.Header[i].Len() > 0 {for e := skipList.Header[i].Front(); e != nil; e = e.Next() {switch {case e.Value.(int) == key:fmt.Println("Found level=", i, " key=", key)return ecase e.Value.(int) > key:break}} //end for} //end if} //end forreturn nil}func (skipList *SkipList) Delete(key int) {for i := len(skipList.Header) - 1; i >= 0; i-- {if skipList.Header[i].Len() > 0 {for e := skipList.Header[i].Front(); e != nil; e = e.Next() {switch {case e.Value.(int) == key:fmt.Println("Delete level=", i, " key=", key)skipList.Header[i].remove(e)case e.Value.(int) > key:break}} //end for} //end if} //end for}func (skipList *SkipList) PrintSkipList() {fmt.Println("\nSkipList-------------------------------------------")for i := SKIPLIST_MAXLEVEL - 1; i >= 0; i-- {fmt.Println("level:", i)if skipList.Header[i].Len() > 0 {for e := skipList.Header[i].Front(); e != nil; e = e.Next() {fmt.Printf("%d ", e.Value)} //end for} //end iffmt.Println("\n--------------------------------------------------------")} //end for}func (skipList *SkipList) Random_level() int {level := 1for (rand.Int31()&0xFFFF)%SKIPLIST_P == 0 {level += 1}if level < SKIPLIST_MAXLEVEL {return level} else {return SKIPLIST_MAXLEVEL}}//////////////////////////////////////////////////////type Node struct {next, prev *Nodelist       *ListValue interface{}}type List struct {root Nodelen  int}func (node *Node) Next() *Node {if p := node.next; node.list != nil && p != &node.list.root {return p}return nil}func (node *Node) Prev() *Node {if p := node.prev; node.list != nil && p != &node.list.root {return p}return nil}func (list *List) Init() *List {list.root.next = &list.rootlist.root.prev = &list.rootlist.len = 0return list}func New() *List {return new(List).Init()}func (list *List) lazyInit() {if list.root.next == nil {list.Init()}}func (list *List) Len() int {return list.len}func (list *List) remove(e *Node) *Node {e.prev.next = e.nexte.next.prev = e.preve.next = nile.prev = nile.list = nillist.len--return e}func (list *List) Remove(e *Node) interface{} {if e.list == list {list.remove(e)}return e.Value}func (list *List) Front() *Node {if list.len == 0 {return nil}return list.root.next}func (list *List) Back() *Node {if list.len == 0 {return nil}return list.root.prev}func (list *List) insert(e, at *Node) *Node {n := at.nextat.next = ee.prev = ate.next = nn.prev = ee.list = listlist.len++return e}func (list *List) insertValue(v interface{}, at *Node) *Node {return list.insert(&Node{Value: v}, at)}func (list *List) InsertBefore(v interface{}, mark *Node) *Node {if mark.list != list {return nil}return list.insertValue(v, mark.prev)}func (list *List) PushBack(v interface{}) *Node {list.lazyInit()return list.insertValue(v, list.root.prev)}

Effect:

SkipList-------------------------------------------level: 7--------------------------------------------------------level: 6--------------------------------------------------------level: 5--------------------------------------------------------level: 4--------------------------------------------------------level: 393--------------------------------------------------------level: 236 93--------------------------------------------------------level: 16 10 22 23 25 36 42 47 48 54 55 61 72 75 78 82 89 93--------------------------------------------------------level: 01 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 8384 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100--------------------------------------------------------Found level= 0  key= 20Found level= 2  key= 36Found level= 3  key= 93Delete level= 1  key= 55Delete level= 0  key= 55SkipList-------------------------------------------level: 7--------------------------------------------------------level: 6--------------------------------------------------------level: 5--------------------------------------------------------level: 4--------------------------------------------------------level: 393--------------------------------------------------------level: 236 93--------------------------------------------------------level: 16 10 22 23 25 36 42 47 48 54 61 72 75 78 82 89 93--------------------------------------------------------level: 01 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 8485 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100--------------------------------------------------------
Done.

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.