From e4b55ae1296a05811507f8dbe2794cd46d693b3d Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:39:27 +0800 Subject: [PATCH 01/22] Add files via upload --- SkipList.go | 111 +++++++++++++++++++++++++++++++++++++++++++++++ Skiplist_test.go | 15 +++++++ 2 files changed, 126 insertions(+) create mode 100644 SkipList.go create mode 100644 Skiplist_test.go diff --git a/SkipList.go b/SkipList.go new file mode 100644 index 0000000..fcddc34 --- /dev/null +++ b/SkipList.go @@ -0,0 +1,111 @@ +package SkipList + +import ( +"math/rand" +) + +type SkipListNode struct { + + key int + + data int + + next []*SkipListNode + +} +type SkipList struct { + head *SkipListNode + + tail *SkipListNode + + length int + + level int + rand *rand.Rand + +} + +func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 + + level := 1 + + for ; level < list.level && list.rand.Uint32() & 0x1 == 1; level ++{} + + return level + +} + +func (list *SkipList)insert(key int, data int)(bool){ + level := list.randomLevel() + update := make([]*SkipListNode,level,level) + node := list.head + for index := level-1;index>=0;index--{ + for{ + node1 := node.next[index] + if node1 == list.tail || node1.key > key{ + update[index] = node + break + } else if node1.key == key{ + node1.data = data + return true + } else{ + node = node1 // 往后查找 + } + } + } + newNode := &SkipListNode{key, data, make([]*SkipListNode,level,level)} + + for index, node:=range update{ + node.next[index], newNode.next[index] = newNode,node.next[index] + } + + list.length++ + return true +} + +func (list *SkipList)delete(key int)bool{ + node := list.head + remove := make([]*SkipListNode,list.level,list.level) + var target *SkipListNode + for index:=len(node.next)-1;index>=0;index--{ + for{ + node1 := node.next[index] + if (node1 == nil || node1.key>key){ + break + }else if (node1.key==key){ + remove[index] = node //需要更改next的元素(目标各层的前一个元素) + target = node1 + break + } else { + node = node1 + } + } + } + if target != nil{ + for index,node1:=range remove{ //此时node1为目标各层的前一个元素 + if node1 != nil{ + node1.next[index] = target.next[index] //更改各next + } + } + list.length-- + return true + } + return false +} + +func (list *SkipList)search(key int)int{ + node := list.head + for index:=len(node.next)-1;index>=0;index--{ + node1 := node.next[index] + for{ + if node1 == nil || node1.key>key{ + break + }else if node1.key == key{ + return node1.data + }else{ + node = node1 + } + } + } + return -1 +} diff --git a/Skiplist_test.go b/Skiplist_test.go new file mode 100644 index 0000000..b34524f --- /dev/null +++ b/Skiplist_test.go @@ -0,0 +1,15 @@ +package SkipList + + +import ( + "testing" +) +func TestInsertion(t *testing.T){ + head := SkipListNode{} + list := SkipList{head:&head, tail:nil} + for i:=0;i<=100;i++{ + if (*SkipList).insert(&list,i,i){ + t.Error(`Insertion failed`) + } + } +} \ No newline at end of file From 045912bfac2c21dcfb6e22abd8caddd02138be6c Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:41:35 +0800 Subject: [PATCH 02/22] Add files via upload --- collections/SkipList.go | 111 +++++++++++++++++++++++++++++++++++ collections/Skiplist_test.go | 15 +++++ 2 files changed, 126 insertions(+) create mode 100644 collections/SkipList.go create mode 100644 collections/Skiplist_test.go diff --git a/collections/SkipList.go b/collections/SkipList.go new file mode 100644 index 0000000..fcddc34 --- /dev/null +++ b/collections/SkipList.go @@ -0,0 +1,111 @@ +package SkipList + +import ( +"math/rand" +) + +type SkipListNode struct { + + key int + + data int + + next []*SkipListNode + +} +type SkipList struct { + head *SkipListNode + + tail *SkipListNode + + length int + + level int + rand *rand.Rand + +} + +func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 + + level := 1 + + for ; level < list.level && list.rand.Uint32() & 0x1 == 1; level ++{} + + return level + +} + +func (list *SkipList)insert(key int, data int)(bool){ + level := list.randomLevel() + update := make([]*SkipListNode,level,level) + node := list.head + for index := level-1;index>=0;index--{ + for{ + node1 := node.next[index] + if node1 == list.tail || node1.key > key{ + update[index] = node + break + } else if node1.key == key{ + node1.data = data + return true + } else{ + node = node1 // 往后查找 + } + } + } + newNode := &SkipListNode{key, data, make([]*SkipListNode,level,level)} + + for index, node:=range update{ + node.next[index], newNode.next[index] = newNode,node.next[index] + } + + list.length++ + return true +} + +func (list *SkipList)delete(key int)bool{ + node := list.head + remove := make([]*SkipListNode,list.level,list.level) + var target *SkipListNode + for index:=len(node.next)-1;index>=0;index--{ + for{ + node1 := node.next[index] + if (node1 == nil || node1.key>key){ + break + }else if (node1.key==key){ + remove[index] = node //需要更改next的元素(目标各层的前一个元素) + target = node1 + break + } else { + node = node1 + } + } + } + if target != nil{ + for index,node1:=range remove{ //此时node1为目标各层的前一个元素 + if node1 != nil{ + node1.next[index] = target.next[index] //更改各next + } + } + list.length-- + return true + } + return false +} + +func (list *SkipList)search(key int)int{ + node := list.head + for index:=len(node.next)-1;index>=0;index--{ + node1 := node.next[index] + for{ + if node1 == nil || node1.key>key{ + break + }else if node1.key == key{ + return node1.data + }else{ + node = node1 + } + } + } + return -1 +} diff --git a/collections/Skiplist_test.go b/collections/Skiplist_test.go new file mode 100644 index 0000000..b34524f --- /dev/null +++ b/collections/Skiplist_test.go @@ -0,0 +1,15 @@ +package SkipList + + +import ( + "testing" +) +func TestInsertion(t *testing.T){ + head := SkipListNode{} + list := SkipList{head:&head, tail:nil} + for i:=0;i<=100;i++{ + if (*SkipList).insert(&list,i,i){ + t.Error(`Insertion failed`) + } + } +} \ No newline at end of file From aaafada03a72bc9deeb69374bc11b0d3faa95f48 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:43:18 +0800 Subject: [PATCH 03/22] Delete SkipList.go --- SkipList.go | 111 ---------------------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 SkipList.go diff --git a/SkipList.go b/SkipList.go deleted file mode 100644 index fcddc34..0000000 --- a/SkipList.go +++ /dev/null @@ -1,111 +0,0 @@ -package SkipList - -import ( -"math/rand" -) - -type SkipListNode struct { - - key int - - data int - - next []*SkipListNode - -} -type SkipList struct { - head *SkipListNode - - tail *SkipListNode - - length int - - level int - rand *rand.Rand - -} - -func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 - - level := 1 - - for ; level < list.level && list.rand.Uint32() & 0x1 == 1; level ++{} - - return level - -} - -func (list *SkipList)insert(key int, data int)(bool){ - level := list.randomLevel() - update := make([]*SkipListNode,level,level) - node := list.head - for index := level-1;index>=0;index--{ - for{ - node1 := node.next[index] - if node1 == list.tail || node1.key > key{ - update[index] = node - break - } else if node1.key == key{ - node1.data = data - return true - } else{ - node = node1 // 往后查找 - } - } - } - newNode := &SkipListNode{key, data, make([]*SkipListNode,level,level)} - - for index, node:=range update{ - node.next[index], newNode.next[index] = newNode,node.next[index] - } - - list.length++ - return true -} - -func (list *SkipList)delete(key int)bool{ - node := list.head - remove := make([]*SkipListNode,list.level,list.level) - var target *SkipListNode - for index:=len(node.next)-1;index>=0;index--{ - for{ - node1 := node.next[index] - if (node1 == nil || node1.key>key){ - break - }else if (node1.key==key){ - remove[index] = node //需要更改next的元素(目标各层的前一个元素) - target = node1 - break - } else { - node = node1 - } - } - } - if target != nil{ - for index,node1:=range remove{ //此时node1为目标各层的前一个元素 - if node1 != nil{ - node1.next[index] = target.next[index] //更改各next - } - } - list.length-- - return true - } - return false -} - -func (list *SkipList)search(key int)int{ - node := list.head - for index:=len(node.next)-1;index>=0;index--{ - node1 := node.next[index] - for{ - if node1 == nil || node1.key>key{ - break - }else if node1.key == key{ - return node1.data - }else{ - node = node1 - } - } - } - return -1 -} From ecf13156334b8de30e03f74ad0ce6495c43878b4 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:43:28 +0800 Subject: [PATCH 04/22] Delete Skiplist_test.go --- Skiplist_test.go | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 Skiplist_test.go diff --git a/Skiplist_test.go b/Skiplist_test.go deleted file mode 100644 index b34524f..0000000 --- a/Skiplist_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package SkipList - - -import ( - "testing" -) -func TestInsertion(t *testing.T){ - head := SkipListNode{} - list := SkipList{head:&head, tail:nil} - for i:=0;i<=100;i++{ - if (*SkipList).insert(&list,i,i){ - t.Error(`Insertion failed`) - } - } -} \ No newline at end of file From 66bb5577d9a303f3e446abc25b3f15837e038fd7 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:44:07 +0800 Subject: [PATCH 05/22] Rename collections/SkipList.go to collections/skiplist/SkipList.go --- collections/{ => skiplist}/SkipList.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename collections/{ => skiplist}/SkipList.go (100%) diff --git a/collections/SkipList.go b/collections/skiplist/SkipList.go similarity index 100% rename from collections/SkipList.go rename to collections/skiplist/SkipList.go From 60235396baefd423c5e9e67c0062f8b520d8e42f Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:44:39 +0800 Subject: [PATCH 06/22] Rename collections/Skiplist_test.go to collections/skiplist/Skiplist_test.go --- collections/{ => skiplist}/Skiplist_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename collections/{ => skiplist}/Skiplist_test.go (93%) diff --git a/collections/Skiplist_test.go b/collections/skiplist/Skiplist_test.go similarity index 93% rename from collections/Skiplist_test.go rename to collections/skiplist/Skiplist_test.go index b34524f..d6a7848 100644 --- a/collections/Skiplist_test.go +++ b/collections/skiplist/Skiplist_test.go @@ -12,4 +12,4 @@ func TestInsertion(t *testing.T){ t.Error(`Insertion failed`) } } -} \ No newline at end of file +} From 9a18000a74957e8be7b7b6762081ecb862151e34 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:45:24 +0800 Subject: [PATCH 07/22] Rename collections/binary_heap.go to collections/binaryheap/binary_heap.go --- collections/{ => binaryheap}/binary_heap.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename collections/{ => binaryheap}/binary_heap.go (100%) diff --git a/collections/binary_heap.go b/collections/binaryheap/binary_heap.go similarity index 100% rename from collections/binary_heap.go rename to collections/binaryheap/binary_heap.go From a6ecffc0c90dbb2ed8adf44ff114ed4f02d0136f Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 10:46:03 +0800 Subject: [PATCH 08/22] Rename collections/binary_heap_test.go to collections/binaryheap/binary_heap_test.go --- collections/{ => binaryheap}/binary_heap_test.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename collections/{ => binaryheap}/binary_heap_test.go (100%) diff --git a/collections/binary_heap_test.go b/collections/binaryheap/binary_heap_test.go similarity index 100% rename from collections/binary_heap_test.go rename to collections/binaryheap/binary_heap_test.go From 2e3baf77ef01b3c97e11e46ba949297ab9479a65 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Wed, 26 Feb 2020 11:18:17 +0800 Subject: [PATCH 09/22] Add files via upload --- collections/skiplist/SkipList.go | 220 +++++++++++++------------- collections/skiplist/Skiplist_test.go | 30 ++-- 2 files changed, 124 insertions(+), 126 deletions(-) diff --git a/collections/skiplist/SkipList.go b/collections/skiplist/SkipList.go index fcddc34..e405201 100644 --- a/collections/skiplist/SkipList.go +++ b/collections/skiplist/SkipList.go @@ -1,111 +1,109 @@ -package SkipList - -import ( -"math/rand" -) - -type SkipListNode struct { - - key int - - data int - - next []*SkipListNode - -} -type SkipList struct { - head *SkipListNode - - tail *SkipListNode - - length int - - level int - rand *rand.Rand - -} - -func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 - - level := 1 - - for ; level < list.level && list.rand.Uint32() & 0x1 == 1; level ++{} - - return level - -} - -func (list *SkipList)insert(key int, data int)(bool){ - level := list.randomLevel() - update := make([]*SkipListNode,level,level) - node := list.head - for index := level-1;index>=0;index--{ - for{ - node1 := node.next[index] - if node1 == list.tail || node1.key > key{ - update[index] = node - break - } else if node1.key == key{ - node1.data = data - return true - } else{ - node = node1 // 往后查找 - } - } - } - newNode := &SkipListNode{key, data, make([]*SkipListNode,level,level)} - - for index, node:=range update{ - node.next[index], newNode.next[index] = newNode,node.next[index] - } - - list.length++ - return true -} - -func (list *SkipList)delete(key int)bool{ - node := list.head - remove := make([]*SkipListNode,list.level,list.level) - var target *SkipListNode - for index:=len(node.next)-1;index>=0;index--{ - for{ - node1 := node.next[index] - if (node1 == nil || node1.key>key){ - break - }else if (node1.key==key){ - remove[index] = node //需要更改next的元素(目标各层的前一个元素) - target = node1 - break - } else { - node = node1 - } - } - } - if target != nil{ - for index,node1:=range remove{ //此时node1为目标各层的前一个元素 - if node1 != nil{ - node1.next[index] = target.next[index] //更改各next - } - } - list.length-- - return true - } - return false -} - -func (list *SkipList)search(key int)int{ - node := list.head - for index:=len(node.next)-1;index>=0;index--{ - node1 := node.next[index] - for{ - if node1 == nil || node1.key>key{ - break - }else if node1.key == key{ - return node1.data - }else{ - node = node1 - } - } - } - return -1 -} +package SkipList + +import ( + "math/rand" +) + +type SkipListNode struct { + key int + + data int + + next []*SkipListNode +} +type SkipList struct { + head *SkipListNode + + tail *SkipListNode + + length int + + level int + rand *rand.Rand +} + +func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 + + level := 1 + + for ; level < list.level && list.rand.Uint32()&0x1 == 1; level++ { + } + + return level + +} + +func (list *SkipList) insert(key int, data int) bool { + level := list.randomLevel() + update := make([]*SkipListNode, level, level) + node := list.head + for index := level - 1; index >= 0; index-- { + for { + node1 := node.next[index] + if node1 == list.tail || node1.key > key { + update[index] = node + break + } else if node1.key == key { + node1.data = data + return true + } else { + node = node1 // 往后查找 + } + } + } + newNode := &SkipListNode{key, data, make([]*SkipListNode, level, level)} + + for index, node := range update { + node.next[index], newNode.next[index] = newNode, node.next[index] + } + + list.length++ + return true +} + +func (list *SkipList) delete(key int) bool { + node := list.head + remove := make([]*SkipListNode, list.level, list.level) + var target *SkipListNode + for index := len(node.next) - 1; index >= 0; index-- { + for { + node1 := node.next[index] + if node1 == nil || node1.key > key { + break + } else if node1.key == key { + remove[index] = node //需要更改next的元素(目标各层的前一个元素) + target = node1 + break + } else { + node = node1 + } + } + } + if target != nil { + for index, node1 := range remove { //此时node1为目标各层的前一个元素 + if node1 != nil { + node1.next[index] = target.next[index] //更改各next + } + } + list.length-- + return true + } + return false +} + +func (list *SkipList) search(key int) int { + node := list.head + for index := len(node.next) - 1; index >= 0; index-- { + node1 := node.next[index] + for { + if node1 == nil || node1.key > key { + break + } else if node1.key == key { + return node1.data + } else { + node = node1 + } + } + } + return -1 +} diff --git a/collections/skiplist/Skiplist_test.go b/collections/skiplist/Skiplist_test.go index d6a7848..11301c8 100644 --- a/collections/skiplist/Skiplist_test.go +++ b/collections/skiplist/Skiplist_test.go @@ -1,15 +1,15 @@ -package SkipList - - -import ( - "testing" -) -func TestInsertion(t *testing.T){ - head := SkipListNode{} - list := SkipList{head:&head, tail:nil} - for i:=0;i<=100;i++{ - if (*SkipList).insert(&list,i,i){ - t.Error(`Insertion failed`) - } - } -} +package SkipList + +import ( + "testing" +) + +func TestInsertion(t *testing.T) { + head := SkipListNode{} + list := SkipList{head: &head, tail: nil} + for i := 0; i <= 100; i++ { + if (*SkipList).insert(&list, i, i) { + t.Error(`Insertion failed`) + } + } +} From 53205cf9b4bddf390175730485841a33818a0a94 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:01:49 +0800 Subject: [PATCH 10/22] Delete SkipList.go --- collections/skiplist/SkipList.go | 109 ------------------------------- 1 file changed, 109 deletions(-) delete mode 100644 collections/skiplist/SkipList.go diff --git a/collections/skiplist/SkipList.go b/collections/skiplist/SkipList.go deleted file mode 100644 index e405201..0000000 --- a/collections/skiplist/SkipList.go +++ /dev/null @@ -1,109 +0,0 @@ -package SkipList - -import ( - "math/rand" -) - -type SkipListNode struct { - key int - - data int - - next []*SkipListNode -} -type SkipList struct { - head *SkipListNode - - tail *SkipListNode - - length int - - level int - rand *rand.Rand -} - -func (list *SkipList) randomLevel() int { //随机生成的层数要满足P=0.5的几何分布 - - level := 1 - - for ; level < list.level && list.rand.Uint32()&0x1 == 1; level++ { - } - - return level - -} - -func (list *SkipList) insert(key int, data int) bool { - level := list.randomLevel() - update := make([]*SkipListNode, level, level) - node := list.head - for index := level - 1; index >= 0; index-- { - for { - node1 := node.next[index] - if node1 == list.tail || node1.key > key { - update[index] = node - break - } else if node1.key == key { - node1.data = data - return true - } else { - node = node1 // 往后查找 - } - } - } - newNode := &SkipListNode{key, data, make([]*SkipListNode, level, level)} - - for index, node := range update { - node.next[index], newNode.next[index] = newNode, node.next[index] - } - - list.length++ - return true -} - -func (list *SkipList) delete(key int) bool { - node := list.head - remove := make([]*SkipListNode, list.level, list.level) - var target *SkipListNode - for index := len(node.next) - 1; index >= 0; index-- { - for { - node1 := node.next[index] - if node1 == nil || node1.key > key { - break - } else if node1.key == key { - remove[index] = node //需要更改next的元素(目标各层的前一个元素) - target = node1 - break - } else { - node = node1 - } - } - } - if target != nil { - for index, node1 := range remove { //此时node1为目标各层的前一个元素 - if node1 != nil { - node1.next[index] = target.next[index] //更改各next - } - } - list.length-- - return true - } - return false -} - -func (list *SkipList) search(key int) int { - node := list.head - for index := len(node.next) - 1; index >= 0; index-- { - node1 := node.next[index] - for { - if node1 == nil || node1.key > key { - break - } else if node1.key == key { - return node1.data - } else { - node = node1 - } - } - } - return -1 -} From 0bf377f99171face59db2adf8e242ecb48f415e1 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:02:02 +0800 Subject: [PATCH 11/22] Delete Skiplist_test.go --- collections/skiplist/Skiplist_test.go | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 collections/skiplist/Skiplist_test.go diff --git a/collections/skiplist/Skiplist_test.go b/collections/skiplist/Skiplist_test.go deleted file mode 100644 index 11301c8..0000000 --- a/collections/skiplist/Skiplist_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package SkipList - -import ( - "testing" -) - -func TestInsertion(t *testing.T) { - head := SkipListNode{} - list := SkipList{head: &head, tail: nil} - for i := 0; i <= 100; i++ { - if (*SkipList).insert(&list, i, i) { - t.Error(`Insertion failed`) - } - } -} From ee6720e83adee67cf5d8df8d14ceeb5dbd6ed6f1 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:03:17 +0800 Subject: [PATCH 12/22] Create skiplist --- collections/binaryheap/skiplist | 1 + 1 file changed, 1 insertion(+) create mode 100644 collections/binaryheap/skiplist diff --git a/collections/binaryheap/skiplist b/collections/binaryheap/skiplist new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/collections/binaryheap/skiplist @@ -0,0 +1 @@ + From d56a39e4333958e7842945aab71b27c5f5f7a851 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:04:04 +0800 Subject: [PATCH 13/22] Delete skiplist --- collections/binaryheap/skiplist | 1 - 1 file changed, 1 deletion(-) delete mode 100644 collections/binaryheap/skiplist diff --git a/collections/binaryheap/skiplist b/collections/binaryheap/skiplist deleted file mode 100644 index 8b13789..0000000 --- a/collections/binaryheap/skiplist +++ /dev/null @@ -1 +0,0 @@ - From 8abbb5a1df4476d6f20827a5c723e02c50962171 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:05:05 +0800 Subject: [PATCH 14/22] Add files via upload --- collections/binaryheap/SkipList/SkipList.go | 176 ++++++++++++++++++ .../binaryheap/SkipList/SkipList_test.go | 32 ++++ 2 files changed, 208 insertions(+) create mode 100644 collections/binaryheap/SkipList/SkipList.go create mode 100644 collections/binaryheap/SkipList/SkipList_test.go diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go new file mode 100644 index 0000000..619b0a7 --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList.go @@ -0,0 +1,176 @@ +package SkipList + +import ( + "fmt" + "math/rand" + "time" +) + +type ConcurrentSkipList struct { + skipLists []*SKIPLIST + level int +} +// SKIPLIST skiplist +type SKIPLIST struct { + level int + length int32 + head *Node + tail *Node + rand *rand.Rand + //vmutex sync.RWMutex +} + +type Node struct { + index uint64 + value int + nextNodes []*Node +} + +func (s *SKIPLIST) createNode(index uint64 ,value,level int) *Node{ + + newNode := &Node{index, value, make([]*Node,s.randomLevel())} + return newNode +} + +func (s *SKIPLIST) randomLevel() int { + + level := 1 + for ; level < s.level && s.rand.Uint32() & 0x1 == 1; level ++{} + return level + + } + +func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { + // Store all previous value whose index is less than index and whose next value's index is larger than index. + previousNodes := make([]*Node, s.level) + + currentNode := s.head + + // Iterate from top level to bottom level. + for l := s.level - 1; l >= 0; l-- { + // Iterate value util value's index is >= given index. + // The max iterate count is skip list's length. So the worst O(n) is N. + for currentNode.nextNodes[l] != s.tail && currentNode.nextNodes[l].index < index { + currentNode = currentNode.nextNodes[l] + } + + // When next value's index is >= given index, add current value whose index < given index. + previousNodes[l] = currentNode + } + + // Avoid point to tail which will occur panic in Insert and Delete function. + // When the next value is tail. + // The index is larger than the maximum index in the skip list or skip list's length is 0. Don't point to tail. + // When the next value isn't tail. + // Next value's index must >= given index. Point to it. + if currentNode.nextNodes[0] != s.tail { + currentNode = currentNode.nextNodes[0] + } + + return previousNodes, currentNode +} + +func (s *SKIPLIST) insert(index uint64, value int) { + // Write lock and unlock. + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // 如果相应index的节点已存在,直接改值 + if currentNode != s.head && currentNode.index == index { + currentNode.value = value + return + } + + // Make a new value. + newNode := s.createNode(index, value, s.randomLevel()) + + // Adjust pointer. Similar to update linked list. + for i := len(newNode.nextNodes) - 1; i >= 0; i-- { + // Firstly, new value point to next value. + newNode.nextNodes[i] = previousNodes[i].nextNodes[i] + + // Secondly, previous nodes point to new value. + previousNodes[i].nextNodes[i] = newNode + + // Finally, in order to release the slice, point to nil. + previousNodes[i] = nil + } + + // atomic.AddInt32(&s.length, 1) + + // 如果previousNode的长度大于newNode,经历上述清空后还有继续清空previousNode + for i := len(newNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } + + fmt.Println("[+]Insertion success.index=",index) +} + +func (s *SKIPLIST) delete(index uint64) { + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // If skip list length is 0 or could not find value with the given index. + if currentNode != s.head && currentNode.index == index { + // Adjust pointer. Similar to update linked list. + for i := 0; i < len(currentNode.nextNodes); i++ { + previousNodes[i].nextNodes[i] = currentNode.nextNodes[i] + currentNode.nextNodes[i] = nil + previousNodes[i] = nil + } + } + + for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } +} +func (s *SKIPLIST) show(){ + var currentNode *Node = s.head + for i:=s.level-1;i>=0;i--{ + fmt.Print("level:",i+1," ") + for { + if currentNode != nil{ + fmt.Print(currentNode.value," ") + if currentNode.nextNodes[i] != nil{ + fmt.Print("-->") + } + currentNode = currentNode.nextNodes[i] + }else{ + break + } + + } + fmt.Printf("\n") + currentNode = s.head + } +} + +//NEWSKIPLIST Create skiplist +func NEWSKIPLIST(level int) *SKIPLIST { + + list := &SKIPLIST{} + + if level <=0 { + + level =32 + + } + + list.level = level + + list.head = &Node{nextNodes:make([]*Node, level, level)} + + list.tail = nil + + list.rand = rand.New(rand.NewSource(time.Now().UnixNano())) + + for index :=range list.head.nextNodes { + + list.head.nextNodes[index] = list.tail + + } + + return list + + } + diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go new file mode 100644 index 0000000..c6567f8 --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList_test.go @@ -0,0 +1,32 @@ +package SkipList + +import ( + "testing" +) + +func TestInsertion(t *testing.T) { + var i uint64 + var val int = 1 + s := NEWSKIPLIST(6) + for i = 1;i<10;i++{ + s.insert(i,val) + val++ + } +} + +func TestSearch(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1;i<10;i++{ + s.searchWithPreviousNodes(i) + } +} + +func TestDelete(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1;i<10;i++{ + s.delete(i) + } +} + From 80df2c4d311c3118cc688707f33c5c5bcd87f364 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:12:12 +0800 Subject: [PATCH 15/22] Delete SkipList.go --- collections/binaryheap/SkipList/SkipList.go | 176 -------------------- 1 file changed, 176 deletions(-) delete mode 100644 collections/binaryheap/SkipList/SkipList.go diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go deleted file mode 100644 index 619b0a7..0000000 --- a/collections/binaryheap/SkipList/SkipList.go +++ /dev/null @@ -1,176 +0,0 @@ -package SkipList - -import ( - "fmt" - "math/rand" - "time" -) - -type ConcurrentSkipList struct { - skipLists []*SKIPLIST - level int -} -// SKIPLIST skiplist -type SKIPLIST struct { - level int - length int32 - head *Node - tail *Node - rand *rand.Rand - //vmutex sync.RWMutex -} - -type Node struct { - index uint64 - value int - nextNodes []*Node -} - -func (s *SKIPLIST) createNode(index uint64 ,value,level int) *Node{ - - newNode := &Node{index, value, make([]*Node,s.randomLevel())} - return newNode -} - -func (s *SKIPLIST) randomLevel() int { - - level := 1 - for ; level < s.level && s.rand.Uint32() & 0x1 == 1; level ++{} - return level - - } - -func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { - // Store all previous value whose index is less than index and whose next value's index is larger than index. - previousNodes := make([]*Node, s.level) - - currentNode := s.head - - // Iterate from top level to bottom level. - for l := s.level - 1; l >= 0; l-- { - // Iterate value util value's index is >= given index. - // The max iterate count is skip list's length. So the worst O(n) is N. - for currentNode.nextNodes[l] != s.tail && currentNode.nextNodes[l].index < index { - currentNode = currentNode.nextNodes[l] - } - - // When next value's index is >= given index, add current value whose index < given index. - previousNodes[l] = currentNode - } - - // Avoid point to tail which will occur panic in Insert and Delete function. - // When the next value is tail. - // The index is larger than the maximum index in the skip list or skip list's length is 0. Don't point to tail. - // When the next value isn't tail. - // Next value's index must >= given index. Point to it. - if currentNode.nextNodes[0] != s.tail { - currentNode = currentNode.nextNodes[0] - } - - return previousNodes, currentNode -} - -func (s *SKIPLIST) insert(index uint64, value int) { - // Write lock and unlock. - - previousNodes, currentNode := s.searchWithPreviousNodes(index) - - // 如果相应index的节点已存在,直接改值 - if currentNode != s.head && currentNode.index == index { - currentNode.value = value - return - } - - // Make a new value. - newNode := s.createNode(index, value, s.randomLevel()) - - // Adjust pointer. Similar to update linked list. - for i := len(newNode.nextNodes) - 1; i >= 0; i-- { - // Firstly, new value point to next value. - newNode.nextNodes[i] = previousNodes[i].nextNodes[i] - - // Secondly, previous nodes point to new value. - previousNodes[i].nextNodes[i] = newNode - - // Finally, in order to release the slice, point to nil. - previousNodes[i] = nil - } - - // atomic.AddInt32(&s.length, 1) - - // 如果previousNode的长度大于newNode,经历上述清空后还有继续清空previousNode - for i := len(newNode.nextNodes); i < len(previousNodes); i++ { - previousNodes[i] = nil - } - - fmt.Println("[+]Insertion success.index=",index) -} - -func (s *SKIPLIST) delete(index uint64) { - - previousNodes, currentNode := s.searchWithPreviousNodes(index) - - // If skip list length is 0 or could not find value with the given index. - if currentNode != s.head && currentNode.index == index { - // Adjust pointer. Similar to update linked list. - for i := 0; i < len(currentNode.nextNodes); i++ { - previousNodes[i].nextNodes[i] = currentNode.nextNodes[i] - currentNode.nextNodes[i] = nil - previousNodes[i] = nil - } - } - - for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { - previousNodes[i] = nil - } -} -func (s *SKIPLIST) show(){ - var currentNode *Node = s.head - for i:=s.level-1;i>=0;i--{ - fmt.Print("level:",i+1," ") - for { - if currentNode != nil{ - fmt.Print(currentNode.value," ") - if currentNode.nextNodes[i] != nil{ - fmt.Print("-->") - } - currentNode = currentNode.nextNodes[i] - }else{ - break - } - - } - fmt.Printf("\n") - currentNode = s.head - } -} - -//NEWSKIPLIST Create skiplist -func NEWSKIPLIST(level int) *SKIPLIST { - - list := &SKIPLIST{} - - if level <=0 { - - level =32 - - } - - list.level = level - - list.head = &Node{nextNodes:make([]*Node, level, level)} - - list.tail = nil - - list.rand = rand.New(rand.NewSource(time.Now().UnixNano())) - - for index :=range list.head.nextNodes { - - list.head.nextNodes[index] = list.tail - - } - - return list - - } - From dca9461dc8ae6795619ea9eed381dbbe91ef66e9 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:12:24 +0800 Subject: [PATCH 16/22] Delete SkipList_test.go --- .../binaryheap/SkipList/SkipList_test.go | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 collections/binaryheap/SkipList/SkipList_test.go diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go deleted file mode 100644 index c6567f8..0000000 --- a/collections/binaryheap/SkipList/SkipList_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package SkipList - -import ( - "testing" -) - -func TestInsertion(t *testing.T) { - var i uint64 - var val int = 1 - s := NEWSKIPLIST(6) - for i = 1;i<10;i++{ - s.insert(i,val) - val++ - } -} - -func TestSearch(t *testing.T) { - var i uint64 - s := NEWSKIPLIST(6) - for i = 1;i<10;i++{ - s.searchWithPreviousNodes(i) - } -} - -func TestDelete(t *testing.T) { - var i uint64 - s := NEWSKIPLIST(6) - for i = 1;i<10;i++{ - s.delete(i) - } -} - From 78fb1befe766cf29156ab40c279d5347afb04bc0 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:12:49 +0800 Subject: [PATCH 17/22] Add files via upload --- collections/binaryheap/SkipList/SkipList.go | 177 ++++++++++++++++++ .../binaryheap/SkipList/SkipList_test.go | 31 +++ 2 files changed, 208 insertions(+) create mode 100644 collections/binaryheap/SkipList/SkipList.go create mode 100644 collections/binaryheap/SkipList/SkipList_test.go diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go new file mode 100644 index 0000000..1c5ad1f --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList.go @@ -0,0 +1,177 @@ +package SkipList + +import ( + "fmt" + "math/rand" + "time" +) + +type ConcurrentSkipList struct { + skipLists []*SKIPLIST + level int +} + +// SKIPLIST skiplist +type SKIPLIST struct { + level int + length int32 + head *Node + tail *Node + rand *rand.Rand + //vmutex sync.RWMutex +} + +type Node struct { + index uint64 + value int + nextNodes []*Node +} + +func (s *SKIPLIST) createNode(index uint64, value, level int) *Node { + + newNode := &Node{index, value, make([]*Node, s.randomLevel())} + return newNode +} + +func (s *SKIPLIST) randomLevel() int { + + level := 1 + for ; level < s.level && s.rand.Uint32()&0x1 == 1; level++ { + } + return level + +} + +func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { + // Store all previous value whose index is less than index and whose next value's index is larger than index. + previousNodes := make([]*Node, s.level) + + currentNode := s.head + + // Iterate from top level to bottom level. + for l := s.level - 1; l >= 0; l-- { + // Iterate value util value's index is >= given index. + // The max iterate count is skip list's length. So the worst O(n) is N. + for currentNode.nextNodes[l] != s.tail && currentNode.nextNodes[l].index < index { + currentNode = currentNode.nextNodes[l] + } + + // When next value's index is >= given index, add current value whose index < given index. + previousNodes[l] = currentNode + } + + // Avoid point to tail which will occur panic in Insert and Delete function. + // When the next value is tail. + // The index is larger than the maximum index in the skip list or skip list's length is 0. Don't point to tail. + // When the next value isn't tail. + // Next value's index must >= given index. Point to it. + if currentNode.nextNodes[0] != s.tail { + currentNode = currentNode.nextNodes[0] + } + + return previousNodes, currentNode +} + +func (s *SKIPLIST) insert(index uint64, value int) { + // Write lock and unlock. + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // 如果相应index的节点已存在,直接改值 + if currentNode != s.head && currentNode.index == index { + currentNode.value = value + return + } + + // Make a new value. + newNode := s.createNode(index, value, s.randomLevel()) + + // Adjust pointer. Similar to update linked list. + for i := len(newNode.nextNodes) - 1; i >= 0; i-- { + // Firstly, new value point to next value. + newNode.nextNodes[i] = previousNodes[i].nextNodes[i] + + // Secondly, previous nodes point to new value. + previousNodes[i].nextNodes[i] = newNode + + // Finally, in order to release the slice, point to nil. + previousNodes[i] = nil + } + + // atomic.AddInt32(&s.length, 1) + + // 如果previousNode的长度大于newNode,经历上述清空后还有继续清空previousNode + for i := len(newNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } + + fmt.Println("[+]Insertion success.index=", index) +} + +func (s *SKIPLIST) delete(index uint64) { + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // If skip list length is 0 or could not find value with the given index. + if currentNode != s.head && currentNode.index == index { + // Adjust pointer. Similar to update linked list. + for i := 0; i < len(currentNode.nextNodes); i++ { + previousNodes[i].nextNodes[i] = currentNode.nextNodes[i] + currentNode.nextNodes[i] = nil + previousNodes[i] = nil + } + } + + for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } +} +func (s *SKIPLIST) show() { + var currentNode *Node = s.head + for i := s.level - 1; i >= 0; i-- { + fmt.Print("level:", i+1, " ") + for { + if currentNode != nil { + fmt.Print(currentNode.value, " ") + if currentNode.nextNodes[i] != nil { + fmt.Print("-->") + } + currentNode = currentNode.nextNodes[i] + } else { + break + } + + } + fmt.Printf("\n") + currentNode = s.head + } +} + +//NEWSKIPLIST Create skiplist +func NEWSKIPLIST(level int) *SKIPLIST { + + list := &SKIPLIST{} + + if level <= 0 { + + level = 32 + + } + + list.level = level + + list.head = &Node{nextNodes: make([]*Node, level, level)} + + list.tail = nil + + list.rand = rand.New(rand.NewSource(time.Now().UnixNano())) + + for index := range list.head.nextNodes { + + list.head.nextNodes[index] = list.tail + + } + + return list + +} diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go new file mode 100644 index 0000000..b227d17 --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList_test.go @@ -0,0 +1,31 @@ +package SkipList + +import ( + "testing" +) + +func TestInsertion(t *testing.T) { + var i uint64 + var val int = 1 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.insert(i, val) + val++ + } +} + +func TestSearch(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.searchWithPreviousNodes(i) + } +} + +func TestDelete(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.delete(i) + } +} From fbc22e2a7784f12eabcfbf7aa0aeaeed42d5064e Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:41:56 +0800 Subject: [PATCH 18/22] Update SkipList.go --- collections/binaryheap/SkipList/SkipList.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go index 1c5ad1f..5db2107 100644 --- a/collections/binaryheap/SkipList/SkipList.go +++ b/collections/binaryheap/SkipList/SkipList.go @@ -72,7 +72,7 @@ func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { return previousNodes, currentNode } -func (s *SKIPLIST) insert(index uint64, value int) { +func (s *SKIPLIST) insert(index uint64, value int) bool { // Write lock and unlock. previousNodes, currentNode := s.searchWithPreviousNodes(index) @@ -80,7 +80,7 @@ func (s *SKIPLIST) insert(index uint64, value int) { // 如果相应index的节点已存在,直接改值 if currentNode != s.head && currentNode.index == index { currentNode.value = value - return + return true } // Make a new value. @@ -105,10 +105,10 @@ func (s *SKIPLIST) insert(index uint64, value int) { previousNodes[i] = nil } - fmt.Println("[+]Insertion success.index=", index) + return true } -func (s *SKIPLIST) delete(index uint64) { +func (s *SKIPLIST) delete(index uint64) bool{ previousNodes, currentNode := s.searchWithPreviousNodes(index) @@ -125,6 +125,7 @@ func (s *SKIPLIST) delete(index uint64) { for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { previousNodes[i] = nil } + return true } func (s *SKIPLIST) show() { var currentNode *Node = s.head From b3174b79de6e67d57ed9d74385bb203e907fe326 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:42:29 +0800 Subject: [PATCH 19/22] Update SkipList_test.go --- collections/binaryheap/SkipList/SkipList_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go index b227d17..ad055d8 100644 --- a/collections/binaryheap/SkipList/SkipList_test.go +++ b/collections/binaryheap/SkipList/SkipList_test.go @@ -9,7 +9,9 @@ func TestInsertion(t *testing.T) { var val int = 1 s := NEWSKIPLIST(6) for i = 1; i < 10; i++ { - s.insert(i, val) + if !s.insert(i, val){ + t.Error("[-]Insertion failed") + } val++ } } @@ -22,10 +24,20 @@ func TestSearch(t *testing.T) { } } +func TestShow(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.show() + } +} func TestDelete(t *testing.T) { var i uint64 s := NEWSKIPLIST(6) for i = 1; i < 10; i++ { - s.delete(i) + if !s.delete(i){ + t.Error("[-]Deletion failed") + } + } } From 934fb5b73d66ce22c52f499d32e8a5169b284508 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:43:41 +0800 Subject: [PATCH 20/22] Delete SkipList_test.go --- .../binaryheap/SkipList/SkipList_test.go | 43 ------------------- 1 file changed, 43 deletions(-) delete mode 100644 collections/binaryheap/SkipList/SkipList_test.go diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go deleted file mode 100644 index ad055d8..0000000 --- a/collections/binaryheap/SkipList/SkipList_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package SkipList - -import ( - "testing" -) - -func TestInsertion(t *testing.T) { - var i uint64 - var val int = 1 - s := NEWSKIPLIST(6) - for i = 1; i < 10; i++ { - if !s.insert(i, val){ - t.Error("[-]Insertion failed") - } - val++ - } -} - -func TestSearch(t *testing.T) { - var i uint64 - s := NEWSKIPLIST(6) - for i = 1; i < 10; i++ { - s.searchWithPreviousNodes(i) - } -} - -func TestShow(t *testing.T) { - var i uint64 - s := NEWSKIPLIST(6) - for i = 1; i < 10; i++ { - s.show() - } -} -func TestDelete(t *testing.T) { - var i uint64 - s := NEWSKIPLIST(6) - for i = 1; i < 10; i++ { - if !s.delete(i){ - t.Error("[-]Deletion failed") - } - - } -} From a9222c73ae03364b34913d67f85b6e43f31d0034 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:43:58 +0800 Subject: [PATCH 21/22] Delete SkipList.go --- collections/binaryheap/SkipList/SkipList.go | 178 -------------------- 1 file changed, 178 deletions(-) delete mode 100644 collections/binaryheap/SkipList/SkipList.go diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go deleted file mode 100644 index 5db2107..0000000 --- a/collections/binaryheap/SkipList/SkipList.go +++ /dev/null @@ -1,178 +0,0 @@ -package SkipList - -import ( - "fmt" - "math/rand" - "time" -) - -type ConcurrentSkipList struct { - skipLists []*SKIPLIST - level int -} - -// SKIPLIST skiplist -type SKIPLIST struct { - level int - length int32 - head *Node - tail *Node - rand *rand.Rand - //vmutex sync.RWMutex -} - -type Node struct { - index uint64 - value int - nextNodes []*Node -} - -func (s *SKIPLIST) createNode(index uint64, value, level int) *Node { - - newNode := &Node{index, value, make([]*Node, s.randomLevel())} - return newNode -} - -func (s *SKIPLIST) randomLevel() int { - - level := 1 - for ; level < s.level && s.rand.Uint32()&0x1 == 1; level++ { - } - return level - -} - -func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { - // Store all previous value whose index is less than index and whose next value's index is larger than index. - previousNodes := make([]*Node, s.level) - - currentNode := s.head - - // Iterate from top level to bottom level. - for l := s.level - 1; l >= 0; l-- { - // Iterate value util value's index is >= given index. - // The max iterate count is skip list's length. So the worst O(n) is N. - for currentNode.nextNodes[l] != s.tail && currentNode.nextNodes[l].index < index { - currentNode = currentNode.nextNodes[l] - } - - // When next value's index is >= given index, add current value whose index < given index. - previousNodes[l] = currentNode - } - - // Avoid point to tail which will occur panic in Insert and Delete function. - // When the next value is tail. - // The index is larger than the maximum index in the skip list or skip list's length is 0. Don't point to tail. - // When the next value isn't tail. - // Next value's index must >= given index. Point to it. - if currentNode.nextNodes[0] != s.tail { - currentNode = currentNode.nextNodes[0] - } - - return previousNodes, currentNode -} - -func (s *SKIPLIST) insert(index uint64, value int) bool { - // Write lock and unlock. - - previousNodes, currentNode := s.searchWithPreviousNodes(index) - - // 如果相应index的节点已存在,直接改值 - if currentNode != s.head && currentNode.index == index { - currentNode.value = value - return true - } - - // Make a new value. - newNode := s.createNode(index, value, s.randomLevel()) - - // Adjust pointer. Similar to update linked list. - for i := len(newNode.nextNodes) - 1; i >= 0; i-- { - // Firstly, new value point to next value. - newNode.nextNodes[i] = previousNodes[i].nextNodes[i] - - // Secondly, previous nodes point to new value. - previousNodes[i].nextNodes[i] = newNode - - // Finally, in order to release the slice, point to nil. - previousNodes[i] = nil - } - - // atomic.AddInt32(&s.length, 1) - - // 如果previousNode的长度大于newNode,经历上述清空后还有继续清空previousNode - for i := len(newNode.nextNodes); i < len(previousNodes); i++ { - previousNodes[i] = nil - } - - return true -} - -func (s *SKIPLIST) delete(index uint64) bool{ - - previousNodes, currentNode := s.searchWithPreviousNodes(index) - - // If skip list length is 0 or could not find value with the given index. - if currentNode != s.head && currentNode.index == index { - // Adjust pointer. Similar to update linked list. - for i := 0; i < len(currentNode.nextNodes); i++ { - previousNodes[i].nextNodes[i] = currentNode.nextNodes[i] - currentNode.nextNodes[i] = nil - previousNodes[i] = nil - } - } - - for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { - previousNodes[i] = nil - } - return true -} -func (s *SKIPLIST) show() { - var currentNode *Node = s.head - for i := s.level - 1; i >= 0; i-- { - fmt.Print("level:", i+1, " ") - for { - if currentNode != nil { - fmt.Print(currentNode.value, " ") - if currentNode.nextNodes[i] != nil { - fmt.Print("-->") - } - currentNode = currentNode.nextNodes[i] - } else { - break - } - - } - fmt.Printf("\n") - currentNode = s.head - } -} - -//NEWSKIPLIST Create skiplist -func NEWSKIPLIST(level int) *SKIPLIST { - - list := &SKIPLIST{} - - if level <= 0 { - - level = 32 - - } - - list.level = level - - list.head = &Node{nextNodes: make([]*Node, level, level)} - - list.tail = nil - - list.rand = rand.New(rand.NewSource(time.Now().UnixNano())) - - for index := range list.head.nextNodes { - - list.head.nextNodes[index] = list.tail - - } - - return list - -} From 0f4289933ccd2915fc08a0f1d2e2088e42c1ee64 Mon Sep 17 00:00:00 2001 From: Cybsac <30456774+Machinesaac@users.noreply.github.com> Date: Tue, 10 Mar 2020 17:45:00 +0800 Subject: [PATCH 22/22] Add files via upload --- collections/binaryheap/SkipList/SkipList.go | 178 ++++++++++++++++++ .../binaryheap/SkipList/SkipList_test.go | 43 +++++ 2 files changed, 221 insertions(+) create mode 100644 collections/binaryheap/SkipList/SkipList.go create mode 100644 collections/binaryheap/SkipList/SkipList_test.go diff --git a/collections/binaryheap/SkipList/SkipList.go b/collections/binaryheap/SkipList/SkipList.go new file mode 100644 index 0000000..45b8140 --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList.go @@ -0,0 +1,178 @@ +package SkipList + +import ( + "fmt" + "math/rand" + "time" +) + +type ConcurrentSkipList struct { + skipLists []*SKIPLIST + level int +} + +// SKIPLIST skiplist +type SKIPLIST struct { + level int + length int32 + head *Node + tail *Node + rand *rand.Rand + //vmutex sync.RWMutex +} + +type Node struct { + index uint64 + value int + nextNodes []*Node +} + +func (s *SKIPLIST) createNode(index uint64, value, level int) *Node { + + newNode := &Node{index, value, make([]*Node, s.randomLevel())} + return newNode +} + +func (s *SKIPLIST) randomLevel() int { + + level := 1 + for ; level < s.level && s.rand.Uint32()&0x1 == 1; level++ { + } + return level + +} + +func (s *SKIPLIST) searchWithPreviousNodes(index uint64) ([]*Node, *Node) { + // Store all previous value whose index is less than index and whose next value's index is larger than index. + previousNodes := make([]*Node, s.level) + + currentNode := s.head + + // Iterate from top level to bottom level. + for l := s.level - 1; l >= 0; l-- { + // Iterate value util value's index is >= given index. + // The max iterate count is skip list's length. So the worst O(n) is N. + for currentNode.nextNodes[l] != s.tail && currentNode.nextNodes[l].index < index { + currentNode = currentNode.nextNodes[l] + } + + // When next value's index is >= given index, add current value whose index < given index. + previousNodes[l] = currentNode + } + + // Avoid point to tail which will occur panic in Insert and Delete function. + // When the next value is tail. + // The index is larger than the maximum index in the skip list or skip list's length is 0. Don't point to tail. + // When the next value isn't tail. + // Next value's index must >= given index. Point to it. + if currentNode.nextNodes[0] != s.tail { + currentNode = currentNode.nextNodes[0] + } + + return previousNodes, currentNode +} + +func (s *SKIPLIST) insert(index uint64, value int) bool { + // Write lock and unlock. + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // 如果相应index的节点已存在,直接改值 + if currentNode != s.head && currentNode.index == index { + currentNode.value = value + return true + } + + // Make a new value. + newNode := s.createNode(index, value, s.randomLevel()) + + // Adjust pointer. Similar to update linked list. + for i := len(newNode.nextNodes) - 1; i >= 0; i-- { + // Firstly, new value point to next value. + newNode.nextNodes[i] = previousNodes[i].nextNodes[i] + + // Secondly, previous nodes point to new value. + previousNodes[i].nextNodes[i] = newNode + + // Finally, in order to release the slice, point to nil. + previousNodes[i] = nil + } + + // atomic.AddInt32(&s.length, 1) + + // 如果previousNode的长度大于newNode,经历上述清空后还有继续清空previousNode + for i := len(newNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } + + return true +} + +func (s *SKIPLIST) delete(index uint64) bool { + + previousNodes, currentNode := s.searchWithPreviousNodes(index) + + // If skip list length is 0 or could not find value with the given index. + if currentNode != s.head && currentNode.index == index { + // Adjust pointer. Similar to update linked list. + for i := 0; i < len(currentNode.nextNodes); i++ { + previousNodes[i].nextNodes[i] = currentNode.nextNodes[i] + currentNode.nextNodes[i] = nil + previousNodes[i] = nil + } + } + + for i := len(currentNode.nextNodes); i < len(previousNodes); i++ { + previousNodes[i] = nil + } + return true +} +func (s *SKIPLIST) show() { + var currentNode *Node = s.head + for i := s.level - 1; i >= 0; i-- { + fmt.Print("level:", i+1, " ") + for { + if currentNode != nil { + fmt.Print(currentNode.value, " ") + if currentNode.nextNodes[i] != nil { + fmt.Print("-->") + } + currentNode = currentNode.nextNodes[i] + } else { + break + } + + } + fmt.Printf("\n") + currentNode = s.head + } +} + +//NEWSKIPLIST Create skiplist +func NEWSKIPLIST(level int) *SKIPLIST { + + list := &SKIPLIST{} + + if level <= 0 { + + level = 32 + + } + + list.level = level + + list.head = &Node{nextNodes: make([]*Node, level, level)} + + list.tail = nil + + list.rand = rand.New(rand.NewSource(time.Now().UnixNano())) + + for index := range list.head.nextNodes { + + list.head.nextNodes[index] = list.tail + + } + + return list + +} diff --git a/collections/binaryheap/SkipList/SkipList_test.go b/collections/binaryheap/SkipList/SkipList_test.go new file mode 100644 index 0000000..3937b0a --- /dev/null +++ b/collections/binaryheap/SkipList/SkipList_test.go @@ -0,0 +1,43 @@ +package SkipList + +import ( + "testing" +) + +func TestInsertion(t *testing.T) { + var i uint64 + var val int = 1 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + if !s.insert(i, val) { + t.Error("[-]Insertion failed") + } + val++ + } +} + +func TestSearch(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.searchWithPreviousNodes(i) + } +} + +func TestShow(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + s.show() + } +} +func TestDelete(t *testing.T) { + var i uint64 + s := NEWSKIPLIST(6) + for i = 1; i < 10; i++ { + if !s.delete(i) { + t.Error("[-]Deletion failed") + } + + } +}