Skip to content

Commit a541184

Browse files
committed
Add SkipList
1 parent bbee485 commit a541184

File tree

1 file changed

+266
-0
lines changed

1 file changed

+266
-0
lines changed

Skip-List/SkipList.swift

Lines changed: 266 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
// The MIT License (MIT)
2+
3+
// Copyright (c) 2016 Mike Taghavi (mitghi[at]me.com)
4+
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
24+
import Foundation
25+
26+
27+
// Stack from : https://github.com/raywenderlich/swift-algorithm-club/tree/master/Stack
28+
public struct Stack<T> {
29+
private var array = [T]()
30+
31+
public var isEmpty: Bool {
32+
return array.isEmpty
33+
}
34+
35+
public var count: Int {
36+
return array.count
37+
}
38+
39+
public mutating func push(element: T) {
40+
array.append(element)
41+
}
42+
43+
public mutating func pop() -> T? {
44+
return array.popLast()
45+
}
46+
47+
public func peek() -> T? {
48+
return array.last
49+
}
50+
}
51+
52+
extension Stack: SequenceType {
53+
public func generate() -> AnyGenerator<T> {
54+
var curr = self
55+
return AnyGenerator {
56+
_ -> T? in
57+
return curr.pop()
58+
}
59+
}
60+
}
61+
62+
63+
func random() -> Bool {
64+
#if os(Linux)
65+
return random() % 2 == 0
66+
#elseif os(OSX)
67+
return arc4random_uniform(2) == 1
68+
#endif
69+
}
70+
71+
72+
73+
class DataNode<Key: Comparable, Payload>{
74+
internal typealias Node = DataNode<Key,Payload>
75+
76+
internal var key : Key?
77+
internal var data : Payload?
78+
internal var _next : Node?
79+
internal var _down : Node?
80+
81+
internal var next: Node? {
82+
get { return self._next }
83+
set(value) { self._next = value }
84+
}
85+
86+
internal var down:Node? {
87+
get { return self._down }
88+
set(value) { self._down = value }
89+
}
90+
91+
init(key:Key, data:Payload){
92+
self.key = key
93+
self.data = data
94+
}
95+
96+
init(header: Bool){
97+
}
98+
99+
}
100+
101+
102+
class SkipList<Key: Comparable, Payload>{
103+
internal typealias Node = DataNode<Key, Payload>
104+
internal var head: Node?
105+
106+
private func find_head(key:Key) -> Node? {
107+
var current = self.head
108+
var found: Bool = false
109+
110+
while !found {
111+
if let curr = current {
112+
if curr.next == nil { current = curr.down }
113+
else {
114+
if curr.next!.key == key { found = true }
115+
else {
116+
if key < curr.next!.key{ current = curr.down }
117+
else { current = curr.next }
118+
}
119+
}
120+
} else {
121+
break
122+
}
123+
}
124+
125+
if found {
126+
return current
127+
} else {
128+
return nil
129+
}
130+
}
131+
132+
133+
private func insert_head(key:Key, data:Payload) -> Void {
134+
135+
self.head = Node(header: true)
136+
var temp = Node(key:key, data:data)
137+
self.head!.next = temp
138+
var top = temp
139+
140+
while random() {
141+
let newhead = Node(header: true)
142+
temp = Node(key:key, data:data)
143+
temp.down = top
144+
newhead.next = temp
145+
newhead.down = self.head
146+
self.head = newhead
147+
top = temp
148+
}
149+
}
150+
151+
private func insert_rest(key:Key, data:Payload) -> Void {
152+
var stack = Stack<Node>()
153+
var current_head: Node? = self.head
154+
155+
while current_head != nil {
156+
157+
if let next = current_head!._next {
158+
if next.key > key {
159+
stack.push(current_head!)
160+
current_head = next
161+
} else {
162+
current_head = next
163+
}
164+
165+
} else {
166+
stack.push(current_head!)
167+
current_head = current_head!.down
168+
}
169+
170+
}
171+
172+
let lowest = stack.pop()
173+
var temp = Node(key:key, data:data)
174+
temp.next = lowest!.next
175+
lowest!.next = temp
176+
var top = temp
177+
178+
while random() {
179+
if stack.isEmpty {
180+
let newhead = Node(header: true)
181+
temp = Node(key:key, data:data)
182+
temp.down = top
183+
newhead.next = temp
184+
newhead.down = self.head
185+
self.head = newhead
186+
top = temp
187+
} else {
188+
let next = stack.pop()
189+
temp = Node(key:key, data:data)
190+
temp.down = top
191+
temp.next = next!.next
192+
next!.next = temp
193+
top = temp
194+
}
195+
}
196+
}
197+
198+
func search(key:Key) -> Payload? {
199+
guard let item = self.find_head(key) else {
200+
return nil
201+
}
202+
203+
return item.next!.data
204+
}
205+
206+
func remove(key:Key) -> Void {
207+
guard let item = self.find_head(key) else {
208+
return
209+
}
210+
211+
var curr = Optional(item)
212+
213+
while curr != nil {
214+
let node = curr!.next
215+
216+
if node!.key != key { curr = node ; continue }
217+
218+
let node_next = node!.next
219+
curr!.next = node_next
220+
curr = curr!.down
221+
222+
}
223+
224+
}
225+
226+
func insert(key: Key, data:Payload){
227+
if self.head != nil{
228+
if let node = self.find_head(key) {
229+
230+
var curr = node.next
231+
while curr != nil && curr!.key == key{
232+
curr!.data = data
233+
curr = curr!.down
234+
}
235+
236+
} else {
237+
self.insert_rest(key, data:data)
238+
}
239+
240+
} else {
241+
self.insert_head(key, data:data)
242+
}
243+
}
244+
245+
}
246+
247+
248+
class Map<Key: Comparable, Payload>{
249+
var collection: SkipList<Key, Payload>
250+
251+
init(){
252+
self.collection = SkipList<Key, Payload>()
253+
}
254+
255+
func insert(key:Key, data: Payload){
256+
self.collection.insert(key, data:data)
257+
}
258+
259+
func get(key:Key) -> Payload?{
260+
return self.collection.search(key)
261+
}
262+
263+
func remove(key:Key) -> Void {
264+
return self.collection.remove(key)
265+
}
266+
}

0 commit comments

Comments
 (0)