Skip to content

Commit cfb94d0

Browse files
committed
Merge pull request kodecocodes#24 from mitghi/master
Add AVL Tree
2 parents 5dc6a94 + 67a3dc9 commit cfb94d0

File tree

2 files changed

+410
-0
lines changed

2 files changed

+410
-0
lines changed

AVL Tree/AVLTree.swift

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
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+
class TreeNode<Key:Comparable,Payload>{
24+
var key: Key
25+
var value: Payload?
26+
var balance: Int = 0
27+
var leftChild: TreeNode<Key,Payload>?
28+
var rightChild: TreeNode<Key,Payload>?
29+
var parent: TreeNode<Key,Payload>?
30+
31+
init(key: Key, value: Payload?,leftChild: TreeNode<Key,Payload>?, rightChild: TreeNode<Key,Payload>?, parent: TreeNode<Key,Payload>?){
32+
self.key = key
33+
self.value = value
34+
self.leftChild = leftChild
35+
self.rightChild = rightChild
36+
self.parent = parent
37+
}
38+
39+
convenience init(key: Key){
40+
self.init(key: key, value: nil, leftChild: nil, rightChild: nil, parent: nil)
41+
}
42+
43+
convenience init(key: Key,value: Payload){
44+
self.init(key: key, value: value, leftChild: nil, rightChild: nil, parent: nil)
45+
}
46+
47+
var isRoot: Bool {
48+
return self.parent == nil
49+
}
50+
51+
var isLeftChild: Bool {
52+
return self.parent != nil && self.parent!.leftChild === self
53+
}
54+
55+
var isRightChild: Bool {
56+
return self.parent != nil && self.parent!.rightChild === self
57+
}
58+
59+
var hasLeftChild: Bool {
60+
return self.leftChild != nil
61+
}
62+
63+
var isLeaf: Bool {
64+
return self.rightChild == nil && self.leftChild == nil
65+
}
66+
67+
var hasRightChild: Bool {
68+
return self.rightChild != nil
69+
}
70+
71+
var hasAnyChild: Bool {
72+
return self.leftChild != nil || self.rightChild != nil
73+
}
74+
75+
var hasBothChilds: Bool {
76+
return self.leftChild != nil && self.rightChild != nil
77+
}
78+
79+
80+
func findmin() -> TreeNode? {
81+
var curr: TreeNode? = self
82+
while (curr != nil) && curr!.hasLeftChild {
83+
curr = curr!.leftChild
84+
}
85+
return curr
86+
}
87+
88+
func find_successor() -> TreeNode<Key,Payload>? {
89+
var res: TreeNode<Key,Payload>?
90+
91+
if self.hasRightChild{
92+
res = self.rightChild!.findmin()
93+
} else {
94+
if let parent = self.parent {
95+
if self.isLeftChild {
96+
res = parent
97+
} else {
98+
parent.rightChild = nil
99+
res = parent.find_successor()
100+
parent.rightChild = self
101+
}
102+
}
103+
}
104+
105+
return res
106+
}
107+
108+
func spliceout(){
109+
if self.isLeaf {
110+
if self.isLeftChild {
111+
self.parent!.leftChild = nil
112+
} else if self.isRightChild {
113+
self.parent!.rightChild = nil
114+
}
115+
} else if self.hasAnyChild{
116+
if self.hasLeftChild{
117+
self.parent!.leftChild = self.leftChild!
118+
} else {
119+
self.parent!.rightChild = self.rightChild!
120+
}
121+
self.leftChild!.parent = self.parent!
122+
} else {
123+
if self.isLeftChild{
124+
self.parent!.leftChild = self.rightChild!
125+
} else {
126+
self.parent!.rightChild = self.rightChild!
127+
}
128+
self.rightChild!.parent = self.parent!
129+
}
130+
}
131+
132+
func replace_nodedata(key: Key,_ value: Payload, _ leftChild: TreeNode<Key,Payload>?,_ rightChild: TreeNode<Key,Payload>?){
133+
self.key = key
134+
self.value = value
135+
self.leftChild = leftChild
136+
self.rightChild = rightChild
137+
138+
if self.hasLeftChild{
139+
self.leftChild!.parent! = self
140+
}
141+
142+
if self.hasRightChild{
143+
self.rightChild!.parent! = self
144+
}
145+
}
146+
}
147+
148+
class AVLTree<Key:Comparable,Payload> {
149+
var root: TreeNode<Key,Payload>?
150+
var size: Int = 0
151+
152+
func insert(input: Key,_ value: Payload) {
153+
if self.size == 0 {
154+
self.root = TreeNode<Key,Payload>(key:input,value:value)
155+
self.size += 1
156+
return
157+
} else if self.size >= 1 {
158+
159+
self._insert(input,value,self.root)
160+
self.size += 1
161+
}
162+
163+
}
164+
165+
subscript(key: Key) -> Payload? {
166+
get {
167+
return self.get(key)
168+
}
169+
set {
170+
self.insert(key,newValue!)
171+
}
172+
}
173+
174+
private func _insert(input: Key, _ value: Payload, _ node :TreeNode<Key,Payload>?){
175+
if input < node!.key {
176+
if node!.hasLeftChild {
177+
self._insert(input,value, node!.leftChild!)
178+
} else {
179+
node!.leftChild = TreeNode<Key,Payload>(key: input, value: value,leftChild: nil,rightChild: nil,parent:node!)
180+
self.updatebalance(node!.leftChild)
181+
}
182+
} else {
183+
if node!.hasRightChild{
184+
self._insert(input,value,node!.rightChild!)
185+
} else {
186+
node!.rightChild = TreeNode<Key,Payload>(key: input, value: value,leftChild: nil,rightChild: nil,parent:node!)
187+
self.updatebalance(node!.rightChild)
188+
}
189+
}
190+
}
191+
192+
func updatebalance(node: TreeNode<Key,Payload>?){
193+
if node!.balance > 1 || node!.balance < -1 {
194+
self.rebalance(node)
195+
return
196+
197+
} else {
198+
199+
if node!.parent != nil {
200+
if node!.isLeftChild {
201+
node!.parent!.balance += 1
202+
} else if node!.isRightChild{
203+
node!.parent!.balance -= 1
204+
}
205+
206+
if node!.parent!.balance != 0 {
207+
self.updatebalance(node!.parent)
208+
}
209+
}
210+
}
211+
212+
}
213+
214+
func rebalance(node: TreeNode<Key,Payload>?){
215+
if node!.balance < 0 {
216+
if node!.rightChild != nil && node!.rightChild!.balance > 0 {
217+
self.rotateright(node!.rightChild)
218+
self.rotateleft(node)
219+
} else {
220+
self.rotateleft(node)
221+
}
222+
} else if node!.balance > 0 {
223+
if node!.leftChild != nil && node!.leftChild!.balance < 0 {
224+
self.rotateleft(node!.leftChild)
225+
self.rotateright(node)
226+
} else {
227+
self.rotateright(node)
228+
}
229+
}
230+
}
231+
232+
func rotateright(node: TreeNode<Key,Payload>?){
233+
let newroot: TreeNode<Key,Payload>? = node!.leftChild
234+
node!.leftChild = newroot!.rightChild
235+
236+
if newroot!.rightChild != nil{
237+
newroot!.rightChild!.parent = node
238+
}
239+
newroot!.parent = node!.parent
240+
241+
if node!.isRoot {
242+
self.root = newroot
243+
} else {
244+
if node!.isRightChild {
245+
node!.parent!.rightChild = newroot
246+
}else if node!.isLeftChild{
247+
node!.parent!.leftChild = newroot
248+
}
249+
}
250+
newroot!.rightChild = node
251+
node!.parent = newroot
252+
node!.balance = node!.balance + 1 - min(newroot!.balance,0)
253+
newroot!.balance = newroot!.balance + 1 - max(node!.balance,0)
254+
}
255+
256+
func rotateleft(node: TreeNode<Key,Payload>?){
257+
let newroot: TreeNode<Key,Payload>? = node!.rightChild
258+
259+
node!.rightChild = newroot!.leftChild
260+
261+
if newroot!.leftChild != nil {
262+
newroot!.leftChild!.parent = node
263+
}
264+
265+
newroot!.parent = node!.parent
266+
267+
if node!.isRoot {
268+
self.root = newroot
269+
} else {
270+
if node!.isLeftChild {
271+
node!.parent!.leftChild = newroot
272+
}else if node!.isRightChild{
273+
node!.parent!.rightChild = newroot
274+
}
275+
}
276+
newroot!.leftChild = node
277+
node!.parent = newroot
278+
node!.balance = node!.balance + 1 - min(newroot!.balance,0)
279+
newroot!.balance = newroot!.balance + 1 - max(node!.balance,0)
280+
}
281+
282+
func get(input: Key) -> Payload? {
283+
guard self.size >= 1 else { return nil }
284+
let result = self._get(input,self.root)
285+
286+
return result != nil ?
287+
result!.value : nil
288+
}
289+
290+
private func _get(key: Key, _ node: TreeNode<Key,Payload>?) -> TreeNode<Key,Payload>? {
291+
guard node != nil else { return nil }
292+
293+
if key == node!.key { return node }
294+
else if key < node!.key { return self._get(key,node!.leftChild) }
295+
else if key > node!.key { return self._get(key,node!.rightChild) }
296+
297+
return nil
298+
}
299+
300+
func delete(key: Key){
301+
guard self.size >= 1 else { return }
302+
303+
if self.size == 1 {
304+
self.root = nil
305+
self.size -= 1
306+
return
307+
}
308+
309+
let item = self._get(key,self.root)
310+
311+
if let item = item { self._delete(item) }
312+
self.size -= 1
313+
}
314+
315+
private func _delete(item: TreeNode<Key,Payload>){
316+
if item.isLeaf {
317+
if item.isLeftChild{
318+
item.parent!.leftChild = nil
319+
} else if item.isRightChild {
320+
item.parent!.rightChild = nil
321+
}
322+
} else if item.hasBothChilds {
323+
let _item = item.find_successor()
324+
_item!.spliceout()
325+
item.key = _item!.key
326+
item.value = _item!.value
327+
328+
if item.hasAnyChild {
329+
if item.hasBothChilds{
330+
item.balance = max(item.leftChild!.balance,item.rightChild!.balance) + 1
331+
} else if item.hasRightChild {
332+
item.balance = item.rightChild!.balance + 1
333+
} else if item.hasLeftChild {
334+
item.balance = item.leftChild!.balance + 1
335+
}
336+
}
337+
338+
} else if item.hasLeftChild {
339+
if item.isLeftChild {
340+
item.leftChild!.parent = item.parent
341+
item.parent!.leftChild = item.leftChild
342+
item.balance = item.leftChild!.balance + 1
343+
} else if item.isRightChild{
344+
item.leftChild!.parent = item.parent
345+
item.parent!.rightChild = item.rightChild
346+
item.balance = item.rightChild!.balance + 1
347+
} else {
348+
item.replace_nodedata(item.leftChild!.key,item.leftChild!.value!,item.leftChild!.leftChild,item.leftChild!.rightChild)
349+
}
350+
} else if item.hasRightChild{
351+
if item.isRightChild{
352+
item.rightChild!.parent = item.parent
353+
item.parent!.rightChild = item.rightChild
354+
item.balance = item.rightChild!.balance + 1
355+
} else if item.isLeftChild{
356+
item.rightChild!.parent = item.parent
357+
item.parent!.leftChild = item.leftChild
358+
item.balance = item.leftChild!.balance + 1
359+
} else {
360+
item.replace_nodedata(item.rightChild!.key,item.rightChild!.value!,item.rightChild!.leftChild,item.rightChild!.rightChild)
361+
}
362+
}
363+
364+
}
365+
366+
func print_values() {
367+
self._print_values(self.root)
368+
}
369+
370+
private func _print_values(node: TreeNode<Key,Payload>?) {
371+
if let node = node {
372+
self._print_values(node.leftChild)
373+
print("\(node.key) -> \(node.value!). Balance : \(node.balance)")
374+
self._print_values(node.rightChild)
375+
}
376+
}
377+
}
378+
379+

0 commit comments

Comments
 (0)