From 83dea87c62a44e8d180811e4d1b5c9da211dddeb Mon Sep 17 00:00:00 2001 From: barbara Date: Sat, 28 Jan 2017 19:29:21 +0100 Subject: [PATCH 001/528] Splay Tree Initial Commit --- Splay Tree/readme.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Splay Tree/readme.md diff --git a/Splay Tree/readme.md b/Splay Tree/readme.md new file mode 100644 index 000000000..2282502fa --- /dev/null +++ b/Splay Tree/readme.md @@ -0,0 +1 @@ +In progress From eb54bc8544f0d482336878e211269ea43da9a7a7 Mon Sep 17 00:00:00 2001 From: Mike Taghavi Date: Mon, 30 Jan 2017 11:38:32 +0100 Subject: [PATCH 002/528] Add Simulated annealing --- Simulated annealing/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Simulated annealing/README.md diff --git a/Simulated annealing/README.md b/Simulated annealing/README.md new file mode 100644 index 000000000..bee8ffe94 --- /dev/null +++ b/Simulated annealing/README.md @@ -0,0 +1 @@ +# Simulated annealing From a6afbc107e25b96bdb86b9186f4a5794046b004b Mon Sep 17 00:00:00 2001 From: Mike Taghavi Date: Mon, 30 Jan 2017 18:18:50 +0100 Subject: [PATCH 003/528] Initial --- Simulated annealing/README.md | 32 ++++ Simulated annealing/simann.swift | 105 +++++++++++ Simulated annealing/simann_example.swift | 222 +++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 Simulated annealing/simann.swift create mode 100644 Simulated annealing/simann_example.swift diff --git a/Simulated annealing/README.md b/Simulated annealing/README.md index bee8ffe94..e7fe75778 100644 --- a/Simulated annealing/README.md +++ b/Simulated annealing/README.md @@ -1 +1,33 @@ # Simulated annealing + +Simulated Annealing is a nature inspired global optimization technique and a metaheuristic to approximate global maxima in a (often discrete)large search space. The name comes from the process of annealing in metallurgy where a material is heated and cooled down under controlled conditions in order to improve its strength and durabilility. The objective is to find a minimum cost solution in the search space by exploiting properties of a thermodynamic system. +Unlike hill climbing techniques which usually gets stuck in a local maxima ( downward moves are not allowed ), simulated annealing can escape local maxima. The interesting property of simulated annealing is that probability of allowing downward moves is high at the high temperatures and gradually reduced as it cools down. In other words, high temperature relaxes the acceptance criteria for the search space and triggers chaotic behavior of acceptance function in the algorithm (e.x initial/high temperature stages) which should make it possible to escape from local maxima and cooler temperatures narrows it and focuses on improvements. + +Pseucocode + + Input: initial, temperature, coolingRate, acceptance + Output: Sbest + Scurrent <- CreateInitialSolution(initial) + Sbest <- Scurrent + while temperature is not minimum: + Snew <- FindNewSolution(Scurrent) + if acceptance(Energy(Scurrent), Energy(Snew), temperature) > Rand(): + Scurrent = Snew + if Energy(Scurrent) < Energy(Sbest): + Sbest = Scurrent + temperature = temperature * (1-coolingRate) + +Common acceptance criteria : P(accept) <- exp((e-ne)/T) where + e is the current energy ( current solution ), + ne is new energy ( new solution ), + T is current temperature. + + +We use this algorithm to solve a Travelling salesman problem instance with 20 cities. The code is in `simann_example.swift` + +#See also + +[Simulated annealing on Wikipedia](https://en.wikipedia.org/wiki/Simulated_annealing) +[Travelling salesman problem](https://en.wikipedia.org/wiki/Travelling_salesman_problem) + +Written for Swift Algorithm Club by [Mike Taghavi](https://github.com/mitghi) diff --git a/Simulated annealing/simann.swift b/Simulated annealing/simann.swift new file mode 100644 index 000000000..8adfbf817 --- /dev/null +++ b/Simulated annealing/simann.swift @@ -0,0 +1,105 @@ +// The MIT License (MIT) +// Copyright (c) 2017 Mike Taghavi (mitghi[at]me.com) +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#if os(OSX) + import Foundation +#elseif os(Linux) + import Glibc +#endif + +public extension Double { + public static func random(_ lower: Double, _ upper: Double) -> Double { + #if os(OSX) + return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower + #elseif os(Linux) + return (Double(random()) / 0xFFFFFFFF) * (upper - lower) + lower + #endif + } +} + +protocol Clonable { + init(current: Self) +} + +// MARK: - create a clone from instance + +extension Clonable { + func clone() -> Self { + return Self.init(current: self) + } +} + +protocol SAObject: Clonable { + var count: Int { get } + func randSwap(a: Int, b: Int) + func currentEnergy() -> Double + func shuffle() +} + +// MARK: - create a new copy of elements + +extension Array where Element: Clonable { + func clone() -> Array { + var newArray = Array() + for elem in self { + newArray.append(elem.clone()) + } + + return newArray + } +} + +typealias AcceptanceFunc = (Double, Double, Double) -> Double + +func SimulatedAnnealing(initial: T, temperature: Double, coolingRate: Double, acceptance: AcceptanceFunc) -> T { + // Step 1: + // Calculate the initial feasible solution based on a random permutation. + // Set best and current solutions to initial solution + + var temp: Double = temperature + var currentSolution = initial.clone() + currentSolution.shuffle() + var bestSolution = currentSolution.clone() + + // Step 2: + // Repeat while the system is still hot + // Randomly modify the current solution by swapping its elements + // Randomly decide if the new solution ( neighbor ) is acceptable and set current solution accordingly + // Update the best solution *iff* it had improved ( lower energy = improvement ) + // Reduce temperature + + while temp > 1 { + let newSolution: T = currentSolution.clone() + let pos1: Int = Int(arc4random_uniform(UInt32(newSolution.count))) + let pos2: Int = Int(arc4random_uniform(UInt32(newSolution.count))) + newSolution.randSwap(a: pos1, b: pos2) + let currentEnergy: Double = currentSolution.currentEnergy() + let newEnergy: Double = newSolution.currentEnergy() + + if acceptance(currentEnergy, newEnergy, temp) > Double.random(0, 1) { + currentSolution = newSolution.clone() + } + if currentSolution.currentEnergy() < bestSolution.currentEnergy() { + bestSolution = currentSolution.clone() + } + + temp *= 1-coolingRate + } + + return bestSolution +} diff --git a/Simulated annealing/simann_example.swift b/Simulated annealing/simann_example.swift new file mode 100644 index 000000000..a0dfaa19a --- /dev/null +++ b/Simulated annealing/simann_example.swift @@ -0,0 +1,222 @@ +// The MIT License (MIT) +// Copyright (c) 2017 Mike Taghavi (mitghi[at]me.com) +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#if os(OSX) + import Foundation +#elseif os(Linux) + import Glibc +#endif + +public extension Double { + + public static func random(_ lower: Double, _ upper: Double) -> Double { + #if os(OSX) + return (Double(arc4random()) / 0xFFFFFFFF) * (upper - lower) + lower + #elseif os(Linux) + return (Double(random()) / 0xFFFFFFFF) * (upper - lower) + lower + #endif + } +} + +protocol Clonable { + init(current: Self) +} + +extension Clonable { + func clone() -> Self { + return Self.init(current: self) + } +} + +protocol SAObject: Clonable { + var count: Int { get } + func randSwap(a: Int, b: Int) + func currentEnergy() -> Double + func shuffle() +} + +// MARK: - create a new copy of elements + +extension Array where Element: Clonable { + func clone() -> Array { + var newArray = Array() + for elem in self { + newArray.append(elem.clone()) + } + + return newArray + } +} + +typealias Points = [Point] +typealias AcceptanceFunc = (Double, Double, Double) -> Double + +class Point: Clonable { + var x: Int + var y: Int + + init(x: Int, y: Int) { + self.x = x + self.y = y + } + + required init(current: Point){ + self.x = current.x + self.y = current.y + } +} + +// MARK: - string representation + +extension Point: CustomStringConvertible { + public var description: String { + return "Point(\(x), \(y))" + } +} + +// MARK: - return distance between two points using operator '<->' + +infix operator <->: AdditionPrecedence +extension Point { + static func <-> (left: Point, right: Point) -> Double { + let xDistance = (left.x - right.x) + let yDistance = (left.y - right.y) + + return Double(sqrt(Double((xDistance * xDistance) + (yDistance * yDistance)))) + } +} + + +class Tour: SAObject { + var tour: Points + var energy: Double = 0.0 + var count: Int { + get { + return self.tour.count + } + } + + init(points: Points){ + self.tour = points.clone() + } + + required init(current: Tour) { + self.tour = current.tour.clone() + } +} + +// MARK: - calculate current tour distance ( energy ). + +extension Tour { + func randSwap(a: Int, b: Int) -> Void { + let (cpos1, cpos2) = (self[a], self[b]) + self[a] = cpos2 + self[b] = cpos1 + } + + func shuffle() { + for i in stride(from: self.count - 1, through: 1, by: -1) { + let j = Int(arc4random()) % (i + 1) + if i != j { + swap(&self.tour[i], &self.tour[j]) + } + } + } + + func currentEnergy() -> Double { + if self.energy == 0 { + var tourEnergy: Double = 0.0 + for i in 0..destCity + tourEnergy = tourEnergy + e + + } + self.energy = tourEnergy + } + return self.energy + } + +} + +// MARK: - subscript to manipulate elements of Tour. + +extension Tour { + subscript(index: Int) -> Point { + get { + return self.tour[index] + } + set(newValue) { + self.tour[index] = newValue + } + } +} + +func SimulatedAnnealing(initial: T, temperature: Double, coolingRate: Double, acceptance: AcceptanceFunc) -> T { + var temp: Double = temperature + var currentSolution = initial.clone() + currentSolution.shuffle() + var bestSolution = currentSolution.clone() + print("Initial solution: ", bestSolution.currentEnergy()) + + while temp > 1 { + let newSolution: T = currentSolution.clone() + let pos1: Int = Int(arc4random_uniform(UInt32(newSolution.count))) + let pos2: Int = Int(arc4random_uniform(UInt32(newSolution.count))) + newSolution.randSwap(a: pos1, b: pos2) + let currentEnergy: Double = currentSolution.currentEnergy() + let newEnergy: Double = newSolution.currentEnergy() + + if acceptance(currentEnergy, newEnergy, temp) > Double.random(0, 1) { + currentSolution = newSolution.clone() + } + if currentSolution.currentEnergy() < bestSolution.currentEnergy() { + bestSolution = currentSolution.clone() + } + + temp *= 1-coolingRate + } + + print("Best solution: ", bestSolution.currentEnergy()) + return bestSolution +} + +let points: [Point] = [ + (60 , 200), (180, 200), (80 , 180), (140, 180), + (20 , 160), (100, 160), (200, 160), (140, 140), + (40 , 120), (100, 120), (180, 100), (60 , 80) , + (120, 80) , (180, 60) , (20 , 40) , (100, 40) , + (200, 40) , (20 , 20) , (60 , 20) , (160, 20) , + ].map{ Point(x: $0.0, y: $0.1) } + +let acceptance : AcceptanceFunc = { + (e: Double, ne: Double, te: Double) -> Double in + if ne < e { + return 1.0 + } + return exp((e - ne) / te) +} + +let result: Tour = SimulatedAnnealing(initial : Tour(points: points), + temperature : 100000.0, + coolingRate : 0.003, + acceptance : acceptance) From a794dec1522cd0df09b96a2d8744b261b8185f2a Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 30 Jan 2017 18:23:23 +0100 Subject: [PATCH 004/528] Update README.md --- Simulated annealing/README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Simulated annealing/README.md b/Simulated annealing/README.md index e7fe75778..3a36464d7 100644 --- a/Simulated annealing/README.md +++ b/Simulated annealing/README.md @@ -17,10 +17,12 @@ Pseucocode Sbest = Scurrent temperature = temperature * (1-coolingRate) -Common acceptance criteria : P(accept) <- exp((e-ne)/T) where - e is the current energy ( current solution ), - ne is new energy ( new solution ), - T is current temperature. +Common acceptance criteria : + + P(accept) <- exp((e-ne)/T) where + e is the current energy ( current solution ), + ne is new energy ( new solution ), + T is current temperature. We use this algorithm to solve a Travelling salesman problem instance with 20 cities. The code is in `simann_example.swift` @@ -28,6 +30,7 @@ We use this algorithm to solve a Travelling salesman problem instance with 20 ci #See also [Simulated annealing on Wikipedia](https://en.wikipedia.org/wiki/Simulated_annealing) + [Travelling salesman problem](https://en.wikipedia.org/wiki/Travelling_salesman_problem) Written for Swift Algorithm Club by [Mike Taghavi](https://github.com/mitghi) From 94c9b5f2b0306e9924c01486889b69934f34575a Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 19 Feb 2017 16:46:31 +0100 Subject: [PATCH 005/528] initial implementation fro Splay Trees Test in progress Debug in progress Playground in progress Documentation not started --- .../SplayTree.playground/Contents.swift | 7 + .../Sources/SplayTree.swift | 509 ++++++++++++++++ .../contents.xcplayground | 4 + .../contents.xcworkspacedata | 7 + Splay Tree/SplayTree.swift | 552 ++++++++++++++++++ Splay Tree/Tests/Info.plist | 22 + Splay Tree/Tests/SplayTreeTests.swift | 19 + Splay Tree/Tests/Tests-Bridging-Header.h | 4 + .../Tests/Tests.xcodeproj/project.pbxproj | 279 +++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Tests.xcscheme | 101 ++++ 11 files changed, 1511 insertions(+) create mode 100644 Splay Tree/SplayTree.playground/Contents.swift create mode 100644 Splay Tree/SplayTree.playground/Sources/SplayTree.swift create mode 100644 Splay Tree/SplayTree.playground/contents.xcplayground create mode 100644 Splay Tree/SplayTree.playground/playground.xcworkspace/contents.xcworkspacedata create mode 100644 Splay Tree/SplayTree.swift create mode 100644 Splay Tree/Tests/Info.plist create mode 100644 Splay Tree/Tests/SplayTreeTests.swift create mode 100644 Splay Tree/Tests/Tests-Bridging-Header.h create mode 100644 Splay Tree/Tests/Tests.xcodeproj/project.pbxproj create mode 100644 Splay Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Splay Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme diff --git a/Splay Tree/SplayTree.playground/Contents.swift b/Splay Tree/SplayTree.playground/Contents.swift new file mode 100644 index 000000000..951ad4c5c --- /dev/null +++ b/Splay Tree/SplayTree.playground/Contents.swift @@ -0,0 +1,7 @@ +//: Playground - Splay Tree Implementation + + +let splayTree = SplayTree(array: [1]) +splayTree.insert(value: 2) +splayTree.insert(value: 10) +splayTree.insert(value: 6) diff --git a/Splay Tree/SplayTree.playground/Sources/SplayTree.swift b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift new file mode 100644 index 000000000..f0c45e831 --- /dev/null +++ b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift @@ -0,0 +1,509 @@ +/* + * Splay Tree + * + * Based on Binary Search Tree Implementation written by Nicolas Ameghino and Matthijs Hollemans for Swift Algorithms Club + * https://github.com/raywenderlich/swift-algorithm-club/blob/master/Binary%20Search%20Tree + * And extended for the specifics of a Splay Tree by Barbara Martina Rodeker + * + */ + +/** + Represent the 3 possible operations (combinations of rotations) that + could be performed during the Splay phase in Splay Trees + + - zigZag Left child of a right child OR right child of a left child + - zigZig Left child of a left child OR right child of a right child + - zig Only 1 parent and that parent is the root + + */ +public enum SplayOperation { + case zigZag + case zigZig + case zig + + + /** + Splay the given node up to the root of the tree + + - Parameters: + - node SplayTree node to move up to the root + */ + public static func splay(node: SplayTree) { + + while (node.parent != nil) { + operation(forNode: node).apply(onNode: node) + } + } + + /** + Compares the node and its parent and determine + if the rotations should be performed in a zigZag, zigZig or zig case. + + - Parmeters: + - forNode SplayTree node to be checked + - Returns + - Operation Case zigZag - zigZig - zig + */ + private static func operation(forNode node: SplayTree) -> SplayOperation { + + if let parent = node.parent, let grandParent = parent.parent { + if (node.isLeftChild && grandParent.isRightChild) || (node.isRightChild && grandParent.isLeftChild) { + return .zigZag + } + return .zigZig + } + return .zig + } + + /** + Applies the rotation associated to the case + Modifying the splay tree and briging the received node further to the top of the tree + + - Parameters: + - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent + */ + private func apply(onNode node: SplayTree) { + switch self { + case .zigZag: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node, parent: node.parent!) + rotate(child: node, parent: node.parent!) + + case .zigZig: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node.parent!, parent: node.parent!.parent!) + rotate(child: node, parent: node.parent!) + + case .zig: + assert(node.parent != nil && node.parent!.parent == nil, "There should be a parent which is the root") + rotate(child: node, parent: node.parent!) + } + } + + /** + Performs a single rotation from a node to its parent + re-arranging the children properly + */ + private func rotate(child: SplayTree, parent: SplayTree) { + + assert(child.parent != nil && child.parent!.value == parent.value, "Parent and child.parent should match here") + + var grandchildToMode: SplayTree? + if child.isLeftChild { + + grandchildToMode = child.right + child.right = parent + parent.left = grandchildToMode + + } else { + + grandchildToMode = child.left + child.left = parent + parent.right = grandchildToMode + } + + let grandParent = parent.parent + parent.parent = child + child.parent = grandParent + } +} + +public class SplayTree { + + fileprivate(set) public var value: T + fileprivate(set) public var parent: SplayTree? + fileprivate(set) public var left: SplayTree? + fileprivate(set) public var right: SplayTree? + + public init(value: T) { + self.value = value + } + + public convenience init(array: [T]) { + precondition(array.count > 0) + self.init(value: array.first!) + for v in array.dropFirst() { + insert(value: v) + } + } + + public var isRoot: Bool { + return parent == nil + } + + public var isLeaf: Bool { + return left == nil && right == nil + } + + public var isLeftChild: Bool { + return parent?.left === self + } + + public var isRightChild: Bool { + return parent?.right === self + } + + public var hasLeftChild: Bool { + return left != nil + } + + public var hasRightChild: Bool { + return right != nil + } + + public var hasAnyChild: Bool { + return hasLeftChild || hasRightChild + } + + public var hasBothChildren: Bool { + return hasLeftChild && hasRightChild + } + + /* How many nodes are in this subtree. Performance: O(n). */ + public var count: Int { + return (left?.count ?? 0) + 1 + (right?.count ?? 0) + } +} + +// MARK: - Adding items + +extension SplayTree { + + /* + Inserts a new element into the tree. You should only insert elements + at the root, to make to sure this remains a valid binary tree! + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func insert(value: T) { + if value < self.value { + if let left = left { + left.insert(value: value) + } else { + + left = SplayTree(value: value) + left?.parent = self + + if let left = left { + SplayOperation.splay(node: left) + self.parent = nil + self.value = left.value + self.left = left.left + self.right = left.right + } + } + } else { + + if let right = right { + right.insert(value: value) + } else { + + right = SplayTree(value: value) + right?.parent = self + + if let right = right { + SplayOperation.splay(node: right) + self.parent = nil + self.value = right.value + self.left = right.left + self.right = right.right + } + } + } + } +} + +// MARK: - Deleting items + +extension SplayTree { + /* + Deletes a node from the tree. + Returns the node that has replaced this removed one (or nil if this was a + leaf node). That is primarily useful for when you delete the root node, in + which case the tree gets a new root. + Performance: runs in O(h) time, where h is the height of the tree. + */ + @discardableResult public func remove() -> SplayTree? { + let replacement: SplayTree? + + if let left = left { + if let right = right { + replacement = removeNodeWithTwoChildren(left, right) + } else { + // This node only has a left child. The left child replaces the node. + replacement = left + } + } else if let right = right { + // This node only has a right child. The right child replaces the node. + replacement = right + } else { + // This node has no children. We just disconnect it from its parent. + replacement = nil + } + + // Save the parent to splay before reconnecting + var parentToSplay: SplayTree? + if let replacement = replacement { + parentToSplay = replacement.parent + } else { + parentToSplay = self.parent + } + + reconnectParentTo(node: replacement) + + // performs the splay operation + if let parentToSplay = parentToSplay { + SplayOperation.splay(node: parentToSplay) + } + + // The current node is no longer part of the tree, so clean it up. + parent = nil + left = nil + right = nil + + return replacement + } + + private func removeNodeWithTwoChildren(_ left: SplayTree, _ right: SplayTree) -> SplayTree { + // This node has two children. It must be replaced by the smallest + // child that is larger than this node's value, which is the leftmost + // descendent of the right child. + let successor = right.minimum() + + // If this in-order successor has a right child of its own (it cannot + // have a left child by definition), then that must take its place. + successor.remove() + + // Connect our left child with the new node. + successor.left = left + left.parent = successor + + // Connect our right child with the new node. If the right child does + // not have any left children of its own, then the in-order successor + // *is* the right child. + if right !== successor { + successor.right = right + right.parent = successor + } else { + successor.right = nil + } + + // And finally, connect the successor node to our parent. + return successor + } + + private func reconnectParentTo(node: SplayTree?) { + if let parent = parent { + if isLeftChild { + parent.left = node + } else { + parent.right = node + } + } + node?.parent = parent + } +} + +// MARK: - Searching + +extension SplayTree { + + /* + Finds the "highest" node with the specified value. + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func search(value: T) -> SplayTree? { + var node: SplayTree? = self + while case let n? = node { + if value < n.value { + node = n.left + } else if value > n.value { + node = n.right + } else { + + if let node = node { + SplayOperation.splay(node: node) + } + + return node + } + } + + if let node = node { + SplayOperation.splay(node: node) + } + + return nil + } + + public func contains(value: T) -> Bool { + return search(value: value) != nil + } + + /* + Returns the leftmost descendent. O(h) time. + */ + public func minimum() -> SplayTree { + var node = self + while case let next? = node.left { + node = next + } + + SplayOperation.splay(node: node) + + return node + } + + /* + Returns the rightmost descendent. O(h) time. + */ + public func maximum() -> SplayTree { + var node = self + while case let next? = node.right { + node = next + } + + SplayOperation.splay(node: node) + + return node + } + + /* + Calculates the depth of this node, i.e. the distance to the root. + Takes O(h) time. + */ + public func depth() -> Int { + var node = self + var edges = 0 + while case let parent? = node.parent { + node = parent + edges += 1 + } + return edges + } + + /* + Calculates the height of this node, i.e. the distance to the lowest leaf. + Since this looks at all children of this node, performance is O(n). + */ + public func height() -> Int { + if isLeaf { + return 0 + } else { + return 1 + max(left?.height() ?? 0, right?.height() ?? 0) + } + } + + /* + Finds the node whose value precedes our value in sorted order. + */ + public func predecessor() -> SplayTree? { + if let left = left { + return left.maximum() + } else { + var node = self + while case let parent? = node.parent { + if parent.value < value { return parent } + node = parent + } + return nil + } + } + + /* + Finds the node whose value succeeds our value in sorted order. + */ + public func successor() -> SplayTree? { + if let right = right { + return right.minimum() + } else { + var node = self + while case let parent? = node.parent { + if parent.value > value { return parent } + node = parent + } + return nil + } + } +} + +// MARK: - Traversal +extension SplayTree { + + public func traverseInOrder(process: (T) -> Void) { + left?.traverseInOrder(process: process) + process(value) + right?.traverseInOrder(process: process) + } + + public func traversePreOrder(process: (T) -> Void) { + process(value) + left?.traversePreOrder(process: process) + right?.traversePreOrder(process: process) + } + + public func traversePostOrder(process: (T) -> Void) { + left?.traversePostOrder(process: process) + right?.traversePostOrder(process: process) + process(value) + } + + /* + Performs an in-order traversal and collects the results in an array. + */ + public func map(formula: (T) -> T) -> [T] { + var a = [T]() + if let left = left { a += left.map(formula: formula) } + a.append(formula(value)) + if let right = right { a += right.map(formula: formula) } + return a + } +} + +/* + Is this binary tree a valid binary search tree? + */ +extension SplayTree { + + public func isBST(minValue: T, maxValue: T) -> Bool { + if value < minValue || value > maxValue { return false } + let leftBST = left?.isBST(minValue: minValue, maxValue: value) ?? true + let rightBST = right?.isBST(minValue: value, maxValue: maxValue) ?? true + return leftBST && rightBST + } +} + +// MARK: - Debugging + +extension SplayTree: CustomStringConvertible { + public var description: String { + var s = "" + if let left = left { + s += "(\(left.description)) <- " + } + s += "\(value)" + if let right = right { + s += " -> (\(right.description))" + } + return s + } +} + +extension SplayTree: CustomDebugStringConvertible { + public var debugDescription: String { + var s = "value: \(value)" + if let parent = parent { + s += ", parent: \(parent.value)" + } + if let left = left { + s += ", left = [" + left.debugDescription + "]" + } + if let right = right { + s += ", right = [" + right.debugDescription + "]" + } + return s + } + + public func toArray() -> [T] { + return map { $0 } + } +} diff --git a/Splay Tree/SplayTree.playground/contents.xcplayground b/Splay Tree/SplayTree.playground/contents.xcplayground new file mode 100644 index 000000000..5da2641c9 --- /dev/null +++ b/Splay Tree/SplayTree.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Splay Tree/SplayTree.playground/playground.xcworkspace/contents.xcworkspacedata b/Splay Tree/SplayTree.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/Splay Tree/SplayTree.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Splay Tree/SplayTree.swift b/Splay Tree/SplayTree.swift new file mode 100644 index 000000000..727ff8f50 --- /dev/null +++ b/Splay Tree/SplayTree.swift @@ -0,0 +1,552 @@ +/* + * Splay Tree + * + * Based on Binary Search Tree Implementation written by Nicolas Ameghino and Matthijs Hollemans for Swift Algorithms Club + * https://github.com/raywenderlich/swift-algorithm-club/blob/master/Binary%20Search%20Tree + * And extended for the specifics of a Splay Tree by Barbara Martina Rodeker + * + */ + +/** + Represent the 3 possible operations (combinations of rotations) that + could be performed during the Splay phase in Splay Trees + + - zigZag Left child of a right child OR right child of a left child + - zigZig Left child of a left child OR right child of a right child + - zig Only 1 parent and that parent is the root + + */ +public enum SplayOperation { + case zigZag + case zigZig + case zig + + + /** + Splay the given node up to the root of the tree + + - Parameters: + - node SplayTree node to move up to the root + */ + public static func splay(node: SplayTree) { + + while (node.parent != nil) { + operation(forNode: node).apply(onNode: node) + } + } + + /** + Compares the node and its parent and determine + if the rotations should be performed in a zigZag, zigZig or zig case. + + - Parmeters: + - forNode SplayTree node to be checked + - Returns + - Operation Case zigZag - zigZig - zig + */ + private static func operation(forNode node: SplayTree) -> SplayOperation { + + if let parent = node.parent, let _ = parent.parent { + if (node.isLeftChild && parent.isRightChild) || (node.isRightChild && parent.isLeftChild) { + return .zigZag + } + return .zigZig + } + return .zig + } + + /** + Applies the rotation associated to the case + Modifying the splay tree and briging the received node further to the top of the tree + + - Parameters: + - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent + */ + private func apply(onNode node: SplayTree) { + switch self { + case .zigZag: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node, parent: node.parent!) + rotate(child: node, parent: node.parent!) + + case .zigZig: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node.parent!, parent: node.parent!.parent!) + rotate(child: node, parent: node.parent!) + + case .zig: + assert(node.parent != nil && node.parent!.parent == nil, "There should be a parent which is the root") + rotate(child: node, parent: node.parent!) + } + } + + /** + Performs a single rotation from a node to its parent + re-arranging the children properly + */ + private func rotate(child: SplayTree, parent: SplayTree) { + + assert(child.parent != nil && child.parent!.value == parent.value, "Parent and child.parent should match here") + + var grandchildToMode: SplayTree? + if child.isLeftChild { + + grandchildToMode = child.right + child.right = parent + parent.left = grandchildToMode + + } else { + + grandchildToMode = child.left + child.left = parent + parent.right = grandchildToMode + } + + let grandParent = parent.parent + parent.parent = child + child.parent = grandParent + } +} + +public class Node { + + fileprivate(set) public var value: T + fileprivate(set) public var parent: SplayTree? + fileprivate(set) public var left: SplayTree? + fileprivate(set) public var right: SplayTree? + + init(value: T){ + self.value = value + } +} + +public class SplayTree { + + + fileprivate(set) public var root: Node? + public var value: T? { + get { + return root?.value + } + set { + if let value = newValue { + root?.value = value + } + } + } + + fileprivate(set) public var parent: SplayTree? { + get { + return root?.parent + } + set { + root?.parent = newValue + } + } + + fileprivate(set) public var left: SplayTree? { + get { + return root?.left + } + set { + root?.left = newValue + } + } + fileprivate(set) public var right: SplayTree? { + get { + return root?.right + } + set { + root?.right = newValue + } + } + + //MARK: - Initializer + + public init(value: T) { + self.root = Node(value:value) + } + + public var isRoot: Bool { + return parent == nil + } + + public var isLeaf: Bool { + return left == nil && right == nil + } + + public var isLeftChild: Bool { + return parent?.left === self + } + + public var isRightChild: Bool { + return parent?.right === self + } + + public var hasLeftChild: Bool { + return left != nil + } + + public var hasRightChild: Bool { + return right != nil + } + + public var hasAnyChild: Bool { + return hasLeftChild || hasRightChild + } + + public var hasBothChildren: Bool { + return hasLeftChild && hasRightChild + } + + /* How many nodes are in this subtree. Performance: O(n). */ + public var count: Int { + return (left?.count ?? 0) + 1 + (right?.count ?? 0) + } +} + +// MARK: - Adding items + +extension SplayTree { + + /* + Inserts a new element into the tree. You should only insert elements + at the root, to make to sure this remains a valid binary tree! + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func insert(value: T) -> SplayTree? { + if let selfValue = self.value { + if value < selfValue { + if let left = left { + return left.insert(value: value) + } else { + + left = SplayTree(value: value) + left?.parent = self + + if let left = left { + SplayOperation.splay(node: left) + return left + } + } + } else { + + if let right = right { + return right.insert(value: value) + } else { + + right = SplayTree(value: value) + right?.parent = self + + if let right = right { + SplayOperation.splay(node: right) + return right + } + } + } + } else { + self.root = Node(value: value) + return self + } + return nil + } +} + +// MARK: - Deleting items + +extension SplayTree { + /* + Deletes a node from the tree. + Returns the node that has replaced this removed one (or nil if this was a + leaf node). That is primarily useful for when you delete the root node, in + which case the tree gets a new root. + Performance: runs in O(h) time, where h is the height of the tree. + */ + @discardableResult public func remove() -> SplayTree? { + let replacement: SplayTree? + + if let left = left { + if let right = right { + replacement = removeNodeWithTwoChildren(left, right) + } else { + // This node only has a left child. The left child replaces the node. + replacement = left + } + } else if let right = right { + // This node only has a right child. The right child replaces the node. + replacement = right + } else { + // This node has no children. We just disconnect it from its parent. + replacement = nil + } + + // Save the parent to splay before reconnecting + var parentToSplay: SplayTree? + if let replacement = replacement { + parentToSplay = replacement.parent + } else { + parentToSplay = self.parent + } + + reconnectParentTo(node: replacement) + + // performs the splay operation + if let parentToSplay = parentToSplay { + SplayOperation.splay(node: parentToSplay) + } + + // The current node is no longer part of the tree, so clean it up. + parent = nil + left = nil + right = nil + + return replacement + } + + private func removeNodeWithTwoChildren(_ left: SplayTree, _ right: SplayTree) -> SplayTree { + // This node has two children. It must be replaced by the smallest + // child that is larger than this node's value, which is the leftmost + // descendent of the right child. + let successor = right.minimum() + + // If this in-order successor has a right child of its own (it cannot + // have a left child by definition), then that must take its place. + successor.remove() + + // Connect our left child with the new node. + successor.left = left + left.parent = successor + + // Connect our right child with the new node. If the right child does + // not have any left children of its own, then the in-order successor + // *is* the right child. + if right !== successor { + successor.right = right + right.parent = successor + } else { + successor.right = nil + } + + // And finally, connect the successor node to our parent. + return successor + } + + private func reconnectParentTo(node: SplayTree?) { + if let parent = parent { + if isLeftChild { + parent.left = node + } else { + parent.right = node + } + } + node?.parent = parent + } +} + +// MARK: - Searching + +extension SplayTree { + + /* + Finds the "highest" node with the specified value. + Performance: runs in O(h) time, where h is the height of the tree. + */ + public func search(value: T) -> SplayTree? { + var node: SplayTree? = self + while case let n? = node, n.value != nil { + if value < n.value! { + node = n.left + } else if value > n.value! { + node = n.right + } else { + + if let node = node { + SplayOperation.splay(node: node) + } + + return node + } + } + + if let node = node { + SplayOperation.splay(node: node) + } + + return nil + } + + public func contains(value: T) -> Bool { + return search(value: value) != nil + } + + /* + Returns the leftmost descendent. O(h) time. + */ + public func minimum() -> SplayTree { + var node = self + while case let next? = node.left { + node = next + } + + SplayOperation.splay(node: node) + + return node + } + + /* + Returns the rightmost descendent. O(h) time. + */ + public func maximum() -> SplayTree { + var node = self + while case let next? = node.right { + node = next + } + + SplayOperation.splay(node: node) + + return node + } + + /* + Calculates the depth of this node, i.e. the distance to the root. + Takes O(h) time. + */ + public func depth() -> Int { + var node = self + var edges = 0 + while case let parent? = node.parent { + node = parent + edges += 1 + } + return edges + } + + /* + Calculates the height of this node, i.e. the distance to the lowest leaf. + Since this looks at all children of this node, performance is O(n). + */ + public func height() -> Int { + if isLeaf { + return 0 + } else { + return 1 + max(left?.height() ?? 0, right?.height() ?? 0) + } + } + + /* + Finds the node whose value precedes our value in sorted order. + */ + public func predecessor() -> SplayTree? { + if let left = left { + return left.maximum() + } else { + var node = self + while case let parent? = node.parent, parent.value != nil, value != nil { + if parent.value! < value! { return parent } + node = parent + } + return nil + } + } + + /* + Finds the node whose value succeeds our value in sorted order. + */ + public func successor() -> SplayTree? { + if let right = right { + return right.minimum() + } else { + var node = self + while case let parent? = node.parent, parent.value != nil , value != nil { + if parent.value! > value! { return parent } + node = parent + } + return nil + } + } +} + +// MARK: - Traversal +extension SplayTree { + + public func traverseInOrder(process: (T) -> Void) { + left?.traverseInOrder(process: process) + process(value!) + right?.traverseInOrder(process: process) + } + + public func traversePreOrder(process: (T) -> Void) { + process(value!) + left?.traversePreOrder(process: process) + right?.traversePreOrder(process: process) + } + + public func traversePostOrder(process: (T) -> Void) { + left?.traversePostOrder(process: process) + right?.traversePostOrder(process: process) + process(value!) + } + + /* + Performs an in-order traversal and collects the results in an array. + */ + public func map(formula: (T) -> T) -> [T] { + var a = [T]() + if let left = left { a += left.map(formula: formula) } + a.append(formula(value!)) + if let right = right { a += right.map(formula: formula) } + return a + } +} + +/* + Is this binary tree a valid binary search tree? + */ +extension SplayTree { + + public func isBST(minValue: T, maxValue: T) -> Bool { + if let value = value { + if value < minValue || value > maxValue { return false } + let leftBST = left?.isBST(minValue: minValue, maxValue: value) ?? true + let rightBST = right?.isBST(minValue: value, maxValue: maxValue) ?? true + return leftBST && rightBST + } + return false + } +} + +// MARK: - Debugging + +extension SplayTree: CustomStringConvertible { + public var description: String { + var s = "" + if let left = left { + s += "(\(left.description)) <- " + } + s += "\(value)" + if let right = right { + s += " -> (\(right.description))" + } + return s + } +} + +extension SplayTree: CustomDebugStringConvertible { + public var debugDescription: String { + var s = "value: \(value)" + if let parent = parent { + s += ", parent: \(parent.value)" + } + if let left = left { + s += ", left = [" + left.debugDescription + "]" + } + if let right = right { + s += ", right = [" + right.debugDescription + "]" + } + return s + } + + public func toArray() -> [T] { + return map { $0 } + } +} diff --git a/Splay Tree/Tests/Info.plist b/Splay Tree/Tests/Info.plist new file mode 100644 index 000000000..6c6c23c43 --- /dev/null +++ b/Splay Tree/Tests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Splay Tree/Tests/SplayTreeTests.swift b/Splay Tree/Tests/SplayTreeTests.swift new file mode 100644 index 000000000..35bdedb71 --- /dev/null +++ b/Splay Tree/Tests/SplayTreeTests.swift @@ -0,0 +1,19 @@ +import XCTest + +class SplayTreeTests: XCTestCase { + var tree: SplayTree! + + override func setUp() { + super.setUp() + tree = SplayTree(value: 1) + } + + func testElements() { + print(tree) + let tree1 = tree.insert(value: 10) + print(tree1!) + let tree2 = tree1!.insert(value: 2) + print(tree2!) + } + +} diff --git a/Splay Tree/Tests/Tests-Bridging-Header.h b/Splay Tree/Tests/Tests-Bridging-Header.h new file mode 100644 index 000000000..1b2cb5d6d --- /dev/null +++ b/Splay Tree/Tests/Tests-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Splay Tree/Tests/Tests.xcodeproj/project.pbxproj b/Splay Tree/Tests/Tests.xcodeproj/project.pbxproj new file mode 100644 index 000000000..8a900fcd3 --- /dev/null +++ b/Splay Tree/Tests/Tests.xcodeproj/project.pbxproj @@ -0,0 +1,279 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 763F9E771E59DAEF00AC5031 /* SplayTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = 763F9E761E59DAEF00AC5031 /* SplayTree.swift */; }; + 763F9E791E59DAFE00AC5031 /* SplayTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 763F9E781E59DAFE00AC5031 /* SplayTreeTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 056E92A21E25D04D00B30F52 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 056E92A61E25D04D00B30F52 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 763F9E761E59DAEF00AC5031 /* SplayTree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SplayTree.swift; path = ../SplayTree.swift; sourceTree = ""; }; + 763F9E781E59DAFE00AC5031 /* SplayTreeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplayTreeTests.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 056E929F1E25D04D00B30F52 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 056E92851E25D03300B30F52 = { + isa = PBXGroup; + children = ( + 056E92A31E25D04D00B30F52 /* Tests */, + 056E928F1E25D03300B30F52 /* Products */, + ); + sourceTree = ""; + }; + 056E928F1E25D03300B30F52 /* Products */ = { + isa = PBXGroup; + children = ( + 056E92A21E25D04D00B30F52 /* Tests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 056E92A31E25D04D00B30F52 /* Tests */ = { + isa = PBXGroup; + children = ( + 056E92A61E25D04D00B30F52 /* Info.plist */, + 763F9E781E59DAFE00AC5031 /* SplayTreeTests.swift */, + 763F9E761E59DAEF00AC5031 /* SplayTree.swift */, + ); + name = Tests; + sourceTree = SOURCE_ROOT; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 056E92A11E25D04D00B30F52 /* Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 056E92A71E25D04D00B30F52 /* Build configuration list for PBXNativeTarget "Tests" */; + buildPhases = ( + 056E929E1E25D04D00B30F52 /* Sources */, + 056E929F1E25D04D00B30F52 /* Frameworks */, + 056E92A01E25D04D00B30F52 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Tests; + productName = Tests; + productReference = 056E92A21E25D04D00B30F52 /* Tests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 056E92861E25D03300B30F52 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 0820; + ORGANIZATIONNAME = "Swift Algorithm Club"; + TargetAttributes = { + 056E92A11E25D04D00B30F52 = { + CreatedOnToolsVersion = 8.2; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 056E92891E25D03300B30F52 /* Build configuration list for PBXProject "Tests" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 056E92851E25D03300B30F52; + productRefGroup = 056E928F1E25D03300B30F52 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 056E92A11E25D04D00B30F52 /* Tests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 056E92A01E25D04D00B30F52 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 056E929E1E25D04D00B30F52 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 763F9E771E59DAEF00AC5031 /* SplayTree.swift in Sources */, + 763F9E791E59DAFE00AC5031 /* SplayTreeTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 056E92991E25D03300B30F52 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 056E929A1E25D03300B30F52 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.12; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + }; + name = Release; + }; + 056E92A81E25D04D00B30F52 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = Swift.Algorithm.Club.Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Tests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + }; + name = Debug; + }; + 056E92A91E25D04D00B30F52 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = Swift.Algorithm.Club.Tests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Tests-Bridging-Header.h"; + SWIFT_VERSION = 3.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 056E92891E25D03300B30F52 /* Build configuration list for PBXProject "Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 056E92991E25D03300B30F52 /* Debug */, + 056E929A1E25D03300B30F52 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 056E92A71E25D04D00B30F52 /* Build configuration list for PBXNativeTarget "Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 056E92A81E25D04D00B30F52 /* Debug */, + 056E92A91E25D04D00B30F52 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 056E92861E25D03300B30F52 /* Project object */; +} diff --git a/Splay Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Splay Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..6c0ea8493 --- /dev/null +++ b/Splay Tree/Tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Splay Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme b/Splay Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme new file mode 100644 index 000000000..b3f6d696a --- /dev/null +++ b/Splay Tree/Tests/Tests.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From cc973dcb62d310f1af0d08d408c782a57e3523cb Mon Sep 17 00:00:00 2001 From: barbara Date: Fri, 3 Mar 2017 21:01:11 +0100 Subject: [PATCH 006/528] Fixes for connecting nodes during rotations --- Splay Tree/SplayTree.swift | 53 ++++++++++++++++++--------- Splay Tree/Tests/SplayTreeTests.swift | 41 +++++++++++++-------- 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/Splay Tree/SplayTree.swift b/Splay Tree/SplayTree.swift index 727ff8f50..2e008ba50 100644 --- a/Splay Tree/SplayTree.swift +++ b/Splay Tree/SplayTree.swift @@ -44,7 +44,7 @@ public enum SplayOperation { - Returns - Operation Case zigZag - zigZig - zig */ - private static func operation(forNode node: SplayTree) -> SplayOperation { + public static func operation(forNode node: SplayTree) -> SplayOperation { if let parent = node.parent, let _ = parent.parent { if (node.isLeftChild && parent.isRightChild) || (node.isRightChild && parent.isLeftChild) { @@ -62,7 +62,7 @@ public enum SplayOperation { - Parameters: - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent */ - private func apply(onNode node: SplayTree) { + public func apply(onNode node: SplayTree) { switch self { case .zigZag: assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") @@ -84,7 +84,7 @@ public enum SplayOperation { Performs a single rotation from a node to its parent re-arranging the children properly */ - private func rotate(child: SplayTree, parent: SplayTree) { + public func rotate(child: SplayTree, parent: SplayTree) { assert(child.parent != nil && child.parent!.value == parent.value, "Parent and child.parent should match here") @@ -95,16 +95,22 @@ public enum SplayOperation { child.right = parent parent.left = grandchildToMode + + } else { grandchildToMode = child.left child.left = parent parent.right = grandchildToMode - } + } + let grandParent = parent.parent parent.parent = child child.parent = grandParent + + grandParent?.left = child + } } @@ -210,9 +216,15 @@ public class SplayTree { extension SplayTree { /* - Inserts a new element into the tree. You should only insert elements - at the root, to make to sure this remains a valid binary tree! - Performance: runs in O(h) time, where h is the height of the tree. + Inserts a new element into the tree. + Returns the new Tree generated by the insertion. + + - Parameters: + - value T value to be inserted. Will be splayed to the root position + + - Returns + - SplayTree Containing the inserted value in the root node + */ public func insert(value: T) -> SplayTree? { if let selfValue = self.value { @@ -255,14 +267,17 @@ extension SplayTree { // MARK: - Deleting items extension SplayTree { + /* - Deletes a node from the tree. - Returns the node that has replaced this removed one (or nil if this was a - leaf node). That is primarily useful for when you delete the root node, in - which case the tree gets a new root. - Performance: runs in O(h) time, where h is the height of the tree. + Deletes the given node from the tree. + Return the new tree generated by the removal. + The removed node (not necessarily the one containing the value), will be splayed to the root. + + - Returns: + - SplayTree Resulting from the deletion and the splaying of the removed node + */ - @discardableResult public func remove() -> SplayTree? { + public func remove() -> SplayTree? { let replacement: SplayTree? if let left = left { @@ -521,11 +536,13 @@ extension SplayTree: CustomStringConvertible { public var description: String { var s = "" if let left = left { - s += "(\(left.description)) <- " + s += "left: (\(left.description)) <- " + } + if let v = value { + s += "\(v)" } - s += "\(value)" if let right = right { - s += " -> (\(right.description))" + s += " -> (right: \(right.description))" } return s } @@ -534,8 +551,8 @@ extension SplayTree: CustomStringConvertible { extension SplayTree: CustomDebugStringConvertible { public var debugDescription: String { var s = "value: \(value)" - if let parent = parent { - s += ", parent: \(parent.value)" + if let parent = parent, let v = parent.value { + s += ", parent: \(v)" } if let left = left { s += ", left = [" + left.debugDescription + "]" diff --git a/Splay Tree/Tests/SplayTreeTests.swift b/Splay Tree/Tests/SplayTreeTests.swift index 35bdedb71..998c6d3c4 100644 --- a/Splay Tree/Tests/SplayTreeTests.swift +++ b/Splay Tree/Tests/SplayTreeTests.swift @@ -1,19 +1,30 @@ import XCTest class SplayTreeTests: XCTestCase { - var tree: SplayTree! - - override func setUp() { - super.setUp() - tree = SplayTree(value: 1) - } - - func testElements() { - print(tree) - let tree1 = tree.insert(value: 10) - print(tree1!) - let tree2 = tree1!.insert(value: 2) - print(tree2!) - } - + + var tree: SplayTree! + var tree1: SplayTree! + + override func setUp() { + super.setUp() + tree = SplayTree(value: 1) + tree1 = tree.insert(value: 10)?.insert(value: 20)?.insert(value: 3)//?.insert(value: 6)?.insert(value: 100)?.insert(value: 44) + } + + func testInsertion() { + let tree1 = tree.insert(value: 10) + assert(tree1?.root?.value == 10) + + let tree2 = tree1!.insert(value: 2) + assert(tree2?.root?.value == 2) + } + + + func testDeleteExisting() { + print(tree1) + let tree2 = tree1.search(value: 6)?.remove() + + } + + } From 72740a17e7bd9b74716e32f1ef9ef4a92534b302 Mon Sep 17 00:00:00 2001 From: barbara Date: Sat, 4 Mar 2017 09:20:25 +0100 Subject: [PATCH 007/528] Test for search function + fixes for rotations --- Splay Tree/SplayTree.swift | 17 +++++++++-------- Splay Tree/Tests/SplayTreeTests.swift | 7 ++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Splay Tree/SplayTree.swift b/Splay Tree/SplayTree.swift index 2e008ba50..bbe8491e2 100644 --- a/Splay Tree/SplayTree.swift +++ b/Splay Tree/SplayTree.swift @@ -94,7 +94,7 @@ public enum SplayOperation { grandchildToMode = child.right child.right = parent parent.left = grandchildToMode - + grandchildToMode?.parent = parent } else { @@ -102,6 +102,7 @@ public enum SplayOperation { grandchildToMode = child.left child.left = parent parent.right = grandchildToMode + grandchildToMode?.parent = parent } @@ -368,23 +369,23 @@ extension SplayTree { */ public func search(value: T) -> SplayTree? { var node: SplayTree? = self + var nodeParent: SplayTree? = self while case let n? = node, n.value != nil { if value < n.value! { + if n.left != nil { nodeParent = n.left } node = n.left } else if value > n.value! { node = n.right - } else { - - if let node = node { - SplayOperation.splay(node: node) - } - - return node + if n.right != nil { nodeParent = n.right } } } if let node = node { SplayOperation.splay(node: node) + return node + } else if let nodeParent = nodeParent { + SplayOperation.splay(node: nodeParent) + return nodeParent } return nil diff --git a/Splay Tree/Tests/SplayTreeTests.swift b/Splay Tree/Tests/SplayTreeTests.swift index 998c6d3c4..042344193 100644 --- a/Splay Tree/Tests/SplayTreeTests.swift +++ b/Splay Tree/Tests/SplayTreeTests.swift @@ -8,7 +8,7 @@ class SplayTreeTests: XCTestCase { override func setUp() { super.setUp() tree = SplayTree(value: 1) - tree1 = tree.insert(value: 10)?.insert(value: 20)?.insert(value: 3)//?.insert(value: 6)?.insert(value: 100)?.insert(value: 44) + tree1 = tree.insert(value: 10)?.insert(value: 20)?.insert(value: 3)?.insert(value: 6)?.insert(value: 100)?.insert(value: 44) } func testInsertion() { @@ -20,9 +20,10 @@ class SplayTreeTests: XCTestCase { } - func testDeleteExisting() { + func testSearchNonExisting() { print(tree1) - let tree2 = tree1.search(value: 6)?.remove() + let tree2 = tree1.search(value: 5) + assert(tree2?.root?.value == 10) } From 84e75b73e246e76fe8a22c97ef49c9d5277ea35b Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:23:31 +0100 Subject: [PATCH 008/528] Completing implementation + debug fixes of Splay Tree --- Splay Tree/SplayTree.swift | 321 +++++++++++++++++++++---------------- 1 file changed, 186 insertions(+), 135 deletions(-) diff --git a/Splay Tree/SplayTree.swift b/Splay Tree/SplayTree.swift index bbe8491e2..f50af7349 100644 --- a/Splay Tree/SplayTree.swift +++ b/Splay Tree/SplayTree.swift @@ -28,7 +28,7 @@ public enum SplayOperation { - Parameters: - node SplayTree node to move up to the root */ - public static func splay(node: SplayTree) { + public static func splay(node: Node) { while (node.parent != nil) { operation(forNode: node).apply(onNode: node) @@ -44,7 +44,7 @@ public enum SplayOperation { - Returns - Operation Case zigZag - zigZig - zig */ - public static func operation(forNode node: SplayTree) -> SplayOperation { + public static func operation(forNode node: Node) -> SplayOperation { if let parent = node.parent, let _ = parent.parent { if (node.isLeftChild && parent.isRightChild) || (node.isRightChild && parent.isLeftChild) { @@ -62,7 +62,7 @@ public enum SplayOperation { - Parameters: - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent */ - public func apply(onNode node: SplayTree) { + public func apply(onNode node: Node) { switch self { case .zigZag: assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") @@ -84,95 +84,65 @@ public enum SplayOperation { Performs a single rotation from a node to its parent re-arranging the children properly */ - public func rotate(child: SplayTree, parent: SplayTree) { + public func rotate(child: Node, parent: Node) { assert(child.parent != nil && child.parent!.value == parent.value, "Parent and child.parent should match here") - var grandchildToMode: SplayTree? + var grandchildToMode: Node? + if child.isLeftChild { grandchildToMode = child.right - child.right = parent parent.left = grandchildToMode grandchildToMode?.parent = parent + + let grandParent = parent.parent + child.parent = grandParent + + if parent.isLeftChild { + grandParent?.left = child + } else { + grandParent?.right = child + } + + child.right = parent + parent.parent = child } else { grandchildToMode = child.left - child.left = parent parent.right = grandchildToMode grandchildToMode?.parent = parent + let grandParent = parent.parent + child.parent = grandParent + + if parent.isLeftChild { + grandParent?.left = child + } else { + grandParent?.right = child + } + + child.left = parent + parent.parent = child + } - let grandParent = parent.parent - parent.parent = child - child.parent = grandParent - - grandParent?.left = child } } public class Node { - fileprivate(set) public var value: T - fileprivate(set) public var parent: SplayTree? - fileprivate(set) public var left: SplayTree? - fileprivate(set) public var right: SplayTree? + fileprivate(set) public var value: T? + fileprivate(set) public var parent: Node? + fileprivate(set) public var left: Node? + fileprivate(set) public var right: Node? - init(value: T){ + init(value: T) { self.value = value } -} - -public class SplayTree { - - - fileprivate(set) public var root: Node? - public var value: T? { - get { - return root?.value - } - set { - if let value = newValue { - root?.value = value - } - } - } - - fileprivate(set) public var parent: SplayTree? { - get { - return root?.parent - } - set { - root?.parent = newValue - } - } - - fileprivate(set) public var left: SplayTree? { - get { - return root?.left - } - set { - root?.left = newValue - } - } - fileprivate(set) public var right: SplayTree? { - get { - return root?.right - } - set { - root?.right = newValue - } - } - - //MARK: - Initializer - - public init(value: T) { - self.root = Node(value:value) - } public var isRoot: Bool { return parent == nil @@ -212,29 +182,66 @@ public class SplayTree { } } +public class SplayTree { + + internal var root: Node? + + var value: T? { + return root?.value + } + + //MARK: - Initializer + + public init(value: T) { + self.root = Node(value:value) + } + + public func insert(value: T) { + root = root?.insert(value: value) + } + + public func remove(value: T) { + root = root?.remove(value: value) + } + + public func search(value: T) -> Node? { + root = root?.search(value: value) + return root + } + + public func minimum() -> Node? { + root = root?.minimum(splayed: true) + return root + } + + public func maximum() -> Node? { + root = root?.maximum(splayed: true) + return root + } + +} + // MARK: - Adding items -extension SplayTree { +extension Node { /* - Inserts a new element into the tree. - Returns the new Tree generated by the insertion. + Inserts a new element into the node tree. - Parameters: - value T value to be inserted. Will be splayed to the root position - - Returns - - SplayTree Containing the inserted value in the root node - + - Returns: + - Node inserted */ - public func insert(value: T) -> SplayTree? { + public func insert(value: T) -> Node { if let selfValue = self.value { if value < selfValue { if let left = left { return left.insert(value: value) } else { - left = SplayTree(value: value) + left = Node(value: value) left?.parent = self if let left = left { @@ -248,7 +255,7 @@ extension SplayTree { return right.insert(value: value) } else { - right = SplayTree(value: value) + right = Node(value: value) right?.parent = self if let right = right { @@ -257,78 +264,104 @@ extension SplayTree { } } } - } else { - self.root = Node(value: value) - return self } - return nil + return self } } // MARK: - Deleting items -extension SplayTree { +extension Node { /* - Deletes the given node from the tree. + Deletes the given node from the nodes tree. Return the new tree generated by the removal. The removed node (not necessarily the one containing the value), will be splayed to the root. + - Parameters: + - value To be removed + - Returns: - - SplayTree Resulting from the deletion and the splaying of the removed node + - Node Resulting from the deletion and the splaying of the removed node */ - public func remove() -> SplayTree? { - let replacement: SplayTree? + public func remove(value: T) -> Node? { + let replacement: Node? - if let left = left { - if let right = right { - replacement = removeNodeWithTwoChildren(left, right) + if let v = self.value, v == value { + + var parentToSplay: Node? + if let left = left { + if let right = right { + + replacement = removeNodeWithTwoChildren(left, right) + + if let replacement = replacement, + let replacementParent = replacement.parent, + replacementParent.value != self.value { + + parentToSplay = replacement.parent + + } else { + parentToSplay = self.parent + } + + } else { + // This node only has a left child. The left child replaces the node. + replacement = left + parentToSplay = parent + } + } else if let right = right { + // This node only has a right child. The right child replaces the node. + replacement = right + parentToSplay = parent } else { - // This node only has a left child. The left child replaces the node. - replacement = left + // This node has no children. We just disconnect it from its parent. + replacement = nil + parentToSplay = parent } - } else if let right = right { - // This node only has a right child. The right child replaces the node. - replacement = right - } else { - // This node has no children. We just disconnect it from its parent. - replacement = nil - } + + reconnectParentTo(node: replacement) + + // performs the splay operation + if let parentToSplay = parentToSplay { + SplayOperation.splay(node: parentToSplay) + } + + // The current node is no longer part of the tree, so clean it up. + parent = nil + left = nil + right = nil - // Save the parent to splay before reconnecting - var parentToSplay: SplayTree? - if let replacement = replacement { - parentToSplay = replacement.parent + return parentToSplay + + } else if let v = self.value, value < v { + if left != nil { + return left!.remove(value: value) + } else { + let node = self + SplayOperation.splay(node: node) + return node + + } } else { - parentToSplay = self.parent - } - - reconnectParentTo(node: replacement) - - // performs the splay operation - if let parentToSplay = parentToSplay { - SplayOperation.splay(node: parentToSplay) + if right != nil { + return right?.remove(value: value) + } else { + let node = self + SplayOperation.splay(node: node) + return node + + } } - - // The current node is no longer part of the tree, so clean it up. - parent = nil - left = nil - right = nil - - return replacement } - private func removeNodeWithTwoChildren(_ left: SplayTree, _ right: SplayTree) -> SplayTree { + private func removeNodeWithTwoChildren(_ left: Node, _ right: Node) -> Node { // This node has two children. It must be replaced by the smallest // child that is larger than this node's value, which is the leftmost // descendent of the right child. let successor = right.minimum() - // If this in-order successor has a right child of its own (it cannot - // have a left child by definition), then that must take its place. - successor.remove() - // Connect our left child with the new node. successor.left = left left.parent = successor @@ -347,7 +380,7 @@ extension SplayTree { return successor } - private func reconnectParentTo(node: SplayTree?) { + private func reconnectParentTo(node: Node?) { if let parent = parent { if isLeftChild { parent.left = node @@ -361,15 +394,15 @@ extension SplayTree { // MARK: - Searching -extension SplayTree { +extension Node { /* Finds the "highest" node with the specified value. Performance: runs in O(h) time, where h is the height of the tree. */ - public func search(value: T) -> SplayTree? { - var node: SplayTree? = self - var nodeParent: SplayTree? = self + public func search(value: T) -> Node? { + var node: Node? = self + var nodeParent: Node? = self while case let n? = node, n.value != nil { if value < n.value! { if n.left != nil { nodeParent = n.left } @@ -377,6 +410,8 @@ extension SplayTree { } else if value > n.value! { node = n.right if n.right != nil { nodeParent = n.right } + } else { + break } } @@ -398,27 +433,31 @@ extension SplayTree { /* Returns the leftmost descendent. O(h) time. */ - public func minimum() -> SplayTree { + public func minimum(splayed: Bool = false) -> Node { var node = self while case let next? = node.left { node = next } - SplayOperation.splay(node: node) - + if splayed == true { + SplayOperation.splay(node: node) + } + return node } /* Returns the rightmost descendent. O(h) time. */ - public func maximum() -> SplayTree { + public func maximum(splayed: Bool = false) -> Node { var node = self while case let next? = node.right { node = next } - SplayOperation.splay(node: node) + if splayed == true { + SplayOperation.splay(node: node) + } return node } @@ -452,7 +491,7 @@ extension SplayTree { /* Finds the node whose value precedes our value in sorted order. */ - public func predecessor() -> SplayTree? { + public func predecessor() -> Node? { if let left = left { return left.maximum() } else { @@ -468,7 +507,7 @@ extension SplayTree { /* Finds the node whose value succeeds our value in sorted order. */ - public func successor() -> SplayTree? { + public func successor() -> Node? { if let right = right { return right.minimum() } else { @@ -483,7 +522,7 @@ extension SplayTree { } // MARK: - Traversal -extension SplayTree { +extension Node { public func traverseInOrder(process: (T) -> Void) { left?.traverseInOrder(process: process) @@ -518,7 +557,7 @@ extension SplayTree { /* Is this binary tree a valid binary search tree? */ -extension SplayTree { +extension Node { public func isBST(minValue: T, maxValue: T) -> Bool { if let value = value { @@ -533,7 +572,7 @@ extension SplayTree { // MARK: - Debugging -extension SplayTree: CustomStringConvertible { +extension Node: CustomStringConvertible { public var description: String { var s = "" if let left = left { @@ -549,7 +588,13 @@ extension SplayTree: CustomStringConvertible { } } -extension SplayTree: CustomDebugStringConvertible { +extension SplayTree: CustomStringConvertible { + public var description: String { + return root?.description ?? "Empty tree" + } +} + +extension Node: CustomDebugStringConvertible { public var debugDescription: String { var s = "value: \(value)" if let parent = parent, let v = parent.value { @@ -568,3 +613,9 @@ extension SplayTree: CustomDebugStringConvertible { return map { $0 } } } + +extension SplayTree: CustomDebugStringConvertible { + public var debugDescription: String { + return root?.debugDescription ?? "Empty tree" + } +} From efa2f4856c6e80ccd36e8de11f3fb279974d9e3e Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:23:43 +0100 Subject: [PATCH 009/528] Tests for max, min, search, insert and remove --- Splay Tree/Tests/SplayTreeTests.swift | 52 ++++++++++++++++++++------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/Splay Tree/Tests/SplayTreeTests.swift b/Splay Tree/Tests/SplayTreeTests.swift index 042344193..0209f8afe 100644 --- a/Splay Tree/Tests/SplayTreeTests.swift +++ b/Splay Tree/Tests/SplayTreeTests.swift @@ -2,30 +2,58 @@ import XCTest class SplayTreeTests: XCTestCase { - var tree: SplayTree! var tree1: SplayTree! + var tree2: SplayTree! override func setUp() { super.setUp() - tree = SplayTree(value: 1) - tree1 = tree.insert(value: 10)?.insert(value: 20)?.insert(value: 3)?.insert(value: 6)?.insert(value: 100)?.insert(value: 44) + tree1 = SplayTree(value: 1) + + tree2 = SplayTree(value: 1) + tree2.insert(value: 10) + tree2.insert(value: 20) + tree2.insert(value: 3) + tree2.insert(value: 6) + tree2.insert(value: 100) + tree2.insert(value: 44) } func testInsertion() { - let tree1 = tree.insert(value: 10) - assert(tree1?.root?.value == 10) + tree1.insert(value: 10) + assert(tree1.value == 10) - let tree2 = tree1!.insert(value: 2) - assert(tree2?.root?.value == 2) + tree2.insert(value: 2) + assert(tree2.root?.value == 2) } - func testSearchNonExisting() { - print(tree1) - let tree2 = tree1.search(value: 5) - assert(tree2?.root?.value == 10) - + let t = tree2.search(value: 5) + assert(t?.value == 10) + } + + func testSearchExisting() { + let t = tree2.search(value: 6) + assert(t?.value == 6) + } + + func testDeleteExistingOnlyLeftChild() { + tree2.remove(value: 3) + assert(tree2.value == 6) + } + + func testDeleteExistingOnly2Children() { + tree2.remove(value: 6) + assert(tree2.value == 20) } + func testMinimum() { + let v = tree2.minimum() + assert(v?.value == 1) + } + + func testMaximum() { + let v = tree2.maximum() + assert(v?.value == 100) + } } From c27fdde75dc064f55ea7dfdcd5c7d0d4a44aaea6 Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:24:22 +0100 Subject: [PATCH 010/528] Replacing SplayTree implementation inside Playground --- .../Sources/SplayTree.swift | 398 +++++++++++------- 1 file changed, 255 insertions(+), 143 deletions(-) diff --git a/Splay Tree/SplayTree.playground/Sources/SplayTree.swift b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift index f0c45e831..f50af7349 100644 --- a/Splay Tree/SplayTree.playground/Sources/SplayTree.swift +++ b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift @@ -28,7 +28,7 @@ public enum SplayOperation { - Parameters: - node SplayTree node to move up to the root */ - public static func splay(node: SplayTree) { + public static func splay(node: Node) { while (node.parent != nil) { operation(forNode: node).apply(onNode: node) @@ -44,10 +44,10 @@ public enum SplayOperation { - Returns - Operation Case zigZag - zigZig - zig */ - private static func operation(forNode node: SplayTree) -> SplayOperation { + public static func operation(forNode node: Node) -> SplayOperation { - if let parent = node.parent, let grandParent = parent.parent { - if (node.isLeftChild && grandParent.isRightChild) || (node.isRightChild && grandParent.isLeftChild) { + if let parent = node.parent, let _ = parent.parent { + if (node.isLeftChild && parent.isRightChild) || (node.isRightChild && parent.isLeftChild) { return .zigZag } return .zigZig @@ -62,7 +62,7 @@ public enum SplayOperation { - Parameters: - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent */ - private func apply(onNode node: SplayTree) { + public func apply(onNode node: Node) { switch self { case .zigZag: assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") @@ -84,49 +84,66 @@ public enum SplayOperation { Performs a single rotation from a node to its parent re-arranging the children properly */ - private func rotate(child: SplayTree, parent: SplayTree) { + public func rotate(child: Node, parent: Node) { assert(child.parent != nil && child.parent!.value == parent.value, "Parent and child.parent should match here") - var grandchildToMode: SplayTree? + var grandchildToMode: Node? + if child.isLeftChild { grandchildToMode = child.right - child.right = parent parent.left = grandchildToMode - + grandchildToMode?.parent = parent + + let grandParent = parent.parent + child.parent = grandParent + + if parent.isLeftChild { + grandParent?.left = child + } else { + grandParent?.right = child + } + + child.right = parent + parent.parent = child + + } else { grandchildToMode = child.left - child.left = parent parent.right = grandchildToMode + grandchildToMode?.parent = parent + + let grandParent = parent.parent + child.parent = grandParent + + if parent.isLeftChild { + grandParent?.left = child + } else { + grandParent?.right = child + } + + child.left = parent + parent.parent = child + } + - let grandParent = parent.parent - parent.parent = child - child.parent = grandParent } } -public class SplayTree { +public class Node { - fileprivate(set) public var value: T - fileprivate(set) public var parent: SplayTree? - fileprivate(set) public var left: SplayTree? - fileprivate(set) public var right: SplayTree? + fileprivate(set) public var value: T? + fileprivate(set) public var parent: Node? + fileprivate(set) public var left: Node? + fileprivate(set) public var right: Node? - public init(value: T) { + init(value: T) { self.value = value } - public convenience init(array: [T]) { - precondition(array.count > 0) - self.init(value: array.first!) - for v in array.dropFirst() { - insert(value: v) - } - } - public var isRoot: Bool { return parent == nil } @@ -165,114 +182,186 @@ public class SplayTree { } } +public class SplayTree { + + internal var root: Node? + + var value: T? { + return root?.value + } + + //MARK: - Initializer + + public init(value: T) { + self.root = Node(value:value) + } + + public func insert(value: T) { + root = root?.insert(value: value) + } + + public func remove(value: T) { + root = root?.remove(value: value) + } + + public func search(value: T) -> Node? { + root = root?.search(value: value) + return root + } + + public func minimum() -> Node? { + root = root?.minimum(splayed: true) + return root + } + + public func maximum() -> Node? { + root = root?.maximum(splayed: true) + return root + } + +} + // MARK: - Adding items -extension SplayTree { +extension Node { /* - Inserts a new element into the tree. You should only insert elements - at the root, to make to sure this remains a valid binary tree! - Performance: runs in O(h) time, where h is the height of the tree. + Inserts a new element into the node tree. + + - Parameters: + - value T value to be inserted. Will be splayed to the root position + + - Returns: + - Node inserted */ - public func insert(value: T) { - if value < self.value { - if let left = left { - left.insert(value: value) - } else { - - left = SplayTree(value: value) - left?.parent = self - + public func insert(value: T) -> Node { + if let selfValue = self.value { + if value < selfValue { if let left = left { - SplayOperation.splay(node: left) - self.parent = nil - self.value = left.value - self.left = left.left - self.right = left.right + return left.insert(value: value) + } else { + + left = Node(value: value) + left?.parent = self + + if let left = left { + SplayOperation.splay(node: left) + return left + } } - } - } else { - - if let right = right { - right.insert(value: value) } else { - right = SplayTree(value: value) - right?.parent = self - if let right = right { - SplayOperation.splay(node: right) - self.parent = nil - self.value = right.value - self.left = right.left - self.right = right.right + return right.insert(value: value) + } else { + + right = Node(value: value) + right?.parent = self + + if let right = right { + SplayOperation.splay(node: right) + return right + } } } } + return self } } // MARK: - Deleting items -extension SplayTree { +extension Node { + /* - Deletes a node from the tree. - Returns the node that has replaced this removed one (or nil if this was a - leaf node). That is primarily useful for when you delete the root node, in - which case the tree gets a new root. - Performance: runs in O(h) time, where h is the height of the tree. + Deletes the given node from the nodes tree. + Return the new tree generated by the removal. + The removed node (not necessarily the one containing the value), will be splayed to the root. + + - Parameters: + - value To be removed + + - Returns: + - Node Resulting from the deletion and the splaying of the removed node + */ - @discardableResult public func remove() -> SplayTree? { - let replacement: SplayTree? + public func remove(value: T) -> Node? { + let replacement: Node? - if let left = left { - if let right = right { - replacement = removeNodeWithTwoChildren(left, right) + if let v = self.value, v == value { + + var parentToSplay: Node? + if let left = left { + if let right = right { + + replacement = removeNodeWithTwoChildren(left, right) + + if let replacement = replacement, + let replacementParent = replacement.parent, + replacementParent.value != self.value { + + parentToSplay = replacement.parent + + } else { + parentToSplay = self.parent + } + + } else { + // This node only has a left child. The left child replaces the node. + replacement = left + parentToSplay = parent + } + } else if let right = right { + // This node only has a right child. The right child replaces the node. + replacement = right + parentToSplay = parent } else { - // This node only has a left child. The left child replaces the node. - replacement = left + // This node has no children. We just disconnect it from its parent. + replacement = nil + parentToSplay = parent } - } else if let right = right { - // This node only has a right child. The right child replaces the node. - replacement = right - } else { - // This node has no children. We just disconnect it from its parent. - replacement = nil - } + + reconnectParentTo(node: replacement) + + // performs the splay operation + if let parentToSplay = parentToSplay { + SplayOperation.splay(node: parentToSplay) + } + + // The current node is no longer part of the tree, so clean it up. + parent = nil + left = nil + right = nil - // Save the parent to splay before reconnecting - var parentToSplay: SplayTree? - if let replacement = replacement { - parentToSplay = replacement.parent + return parentToSplay + + } else if let v = self.value, value < v { + if left != nil { + return left!.remove(value: value) + } else { + let node = self + SplayOperation.splay(node: node) + return node + + } } else { - parentToSplay = self.parent - } - - reconnectParentTo(node: replacement) - - // performs the splay operation - if let parentToSplay = parentToSplay { - SplayOperation.splay(node: parentToSplay) + if right != nil { + return right?.remove(value: value) + } else { + let node = self + SplayOperation.splay(node: node) + return node + + } } - - // The current node is no longer part of the tree, so clean it up. - parent = nil - left = nil - right = nil - - return replacement } - private func removeNodeWithTwoChildren(_ left: SplayTree, _ right: SplayTree) -> SplayTree { + private func removeNodeWithTwoChildren(_ left: Node, _ right: Node) -> Node { // This node has two children. It must be replaced by the smallest // child that is larger than this node's value, which is the leftmost // descendent of the right child. let successor = right.minimum() - // If this in-order successor has a right child of its own (it cannot - // have a left child by definition), then that must take its place. - successor.remove() - // Connect our left child with the new node. successor.left = left left.parent = successor @@ -291,7 +380,7 @@ extension SplayTree { return successor } - private func reconnectParentTo(node: SplayTree?) { + private func reconnectParentTo(node: Node?) { if let parent = parent { if isLeftChild { parent.left = node @@ -305,31 +394,33 @@ extension SplayTree { // MARK: - Searching -extension SplayTree { +extension Node { /* Finds the "highest" node with the specified value. Performance: runs in O(h) time, where h is the height of the tree. */ - public func search(value: T) -> SplayTree? { - var node: SplayTree? = self - while case let n? = node { - if value < n.value { + public func search(value: T) -> Node? { + var node: Node? = self + var nodeParent: Node? = self + while case let n? = node, n.value != nil { + if value < n.value! { + if n.left != nil { nodeParent = n.left } node = n.left - } else if value > n.value { + } else if value > n.value! { node = n.right + if n.right != nil { nodeParent = n.right } } else { - - if let node = node { - SplayOperation.splay(node: node) - } - - return node + break } } if let node = node { SplayOperation.splay(node: node) + return node + } else if let nodeParent = nodeParent { + SplayOperation.splay(node: nodeParent) + return nodeParent } return nil @@ -342,27 +433,31 @@ extension SplayTree { /* Returns the leftmost descendent. O(h) time. */ - public func minimum() -> SplayTree { + public func minimum(splayed: Bool = false) -> Node { var node = self while case let next? = node.left { node = next } - SplayOperation.splay(node: node) - + if splayed == true { + SplayOperation.splay(node: node) + } + return node } /* Returns the rightmost descendent. O(h) time. */ - public func maximum() -> SplayTree { + public func maximum(splayed: Bool = false) -> Node { var node = self while case let next? = node.right { node = next } - SplayOperation.splay(node: node) + if splayed == true { + SplayOperation.splay(node: node) + } return node } @@ -396,13 +491,13 @@ extension SplayTree { /* Finds the node whose value precedes our value in sorted order. */ - public func predecessor() -> SplayTree? { + public func predecessor() -> Node? { if let left = left { return left.maximum() } else { var node = self - while case let parent? = node.parent { - if parent.value < value { return parent } + while case let parent? = node.parent, parent.value != nil, value != nil { + if parent.value! < value! { return parent } node = parent } return nil @@ -412,13 +507,13 @@ extension SplayTree { /* Finds the node whose value succeeds our value in sorted order. */ - public func successor() -> SplayTree? { + public func successor() -> Node? { if let right = right { return right.minimum() } else { var node = self - while case let parent? = node.parent { - if parent.value > value { return parent } + while case let parent? = node.parent, parent.value != nil , value != nil { + if parent.value! > value! { return parent } node = parent } return nil @@ -427,16 +522,16 @@ extension SplayTree { } // MARK: - Traversal -extension SplayTree { +extension Node { public func traverseInOrder(process: (T) -> Void) { left?.traverseInOrder(process: process) - process(value) + process(value!) right?.traverseInOrder(process: process) } public func traversePreOrder(process: (T) -> Void) { - process(value) + process(value!) left?.traversePreOrder(process: process) right?.traversePreOrder(process: process) } @@ -444,7 +539,7 @@ extension SplayTree { public func traversePostOrder(process: (T) -> Void) { left?.traversePostOrder(process: process) right?.traversePostOrder(process: process) - process(value) + process(value!) } /* @@ -453,7 +548,7 @@ extension SplayTree { public func map(formula: (T) -> T) -> [T] { var a = [T]() if let left = left { a += left.map(formula: formula) } - a.append(formula(value)) + a.append(formula(value!)) if let right = right { a += right.map(formula: formula) } return a } @@ -462,37 +557,48 @@ extension SplayTree { /* Is this binary tree a valid binary search tree? */ -extension SplayTree { +extension Node { public func isBST(minValue: T, maxValue: T) -> Bool { - if value < minValue || value > maxValue { return false } - let leftBST = left?.isBST(minValue: minValue, maxValue: value) ?? true - let rightBST = right?.isBST(minValue: value, maxValue: maxValue) ?? true - return leftBST && rightBST + if let value = value { + if value < minValue || value > maxValue { return false } + let leftBST = left?.isBST(minValue: minValue, maxValue: value) ?? true + let rightBST = right?.isBST(minValue: value, maxValue: maxValue) ?? true + return leftBST && rightBST + } + return false } } // MARK: - Debugging -extension SplayTree: CustomStringConvertible { +extension Node: CustomStringConvertible { public var description: String { var s = "" if let left = left { - s += "(\(left.description)) <- " + s += "left: (\(left.description)) <- " + } + if let v = value { + s += "\(v)" } - s += "\(value)" if let right = right { - s += " -> (\(right.description))" + s += " -> (right: \(right.description))" } return s } } -extension SplayTree: CustomDebugStringConvertible { +extension SplayTree: CustomStringConvertible { + public var description: String { + return root?.description ?? "Empty tree" + } +} + +extension Node: CustomDebugStringConvertible { public var debugDescription: String { var s = "value: \(value)" - if let parent = parent { - s += ", parent: \(parent.value)" + if let parent = parent, let v = parent.value { + s += ", parent: \(v)" } if let left = left { s += ", left = [" + left.debugDescription + "]" @@ -507,3 +613,9 @@ extension SplayTree: CustomDebugStringConvertible { return map { $0 } } } + +extension SplayTree: CustomDebugStringConvertible { + public var debugDescription: String { + return root?.debugDescription ?? "Empty tree" + } +} From 4aaec9d94b5b6a5c75b07c35fd0e4def6830ac44 Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:38:15 +0100 Subject: [PATCH 011/528] Test for root removal and multiple operations executed --- Splay Tree/Tests/SplayTreeTests.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Splay Tree/Tests/SplayTreeTests.swift b/Splay Tree/Tests/SplayTreeTests.swift index 0209f8afe..01201a108 100644 --- a/Splay Tree/Tests/SplayTreeTests.swift +++ b/Splay Tree/Tests/SplayTreeTests.swift @@ -46,6 +46,11 @@ class SplayTreeTests: XCTestCase { assert(tree2.value == 20) } + func testDeleteRoot() { + tree2.remove(value: 44) + assert(tree2.value == 100) + } + func testMinimum() { let v = tree2.minimum() assert(v?.value == 1) @@ -56,4 +61,16 @@ class SplayTreeTests: XCTestCase { assert(v?.value == 100) } + func testInsertionRemovals() { + let splayTree = SplayTree(value: 1) + splayTree.insert(value: 2) + splayTree.insert(value: 10) + splayTree.insert(value: 6) + + splayTree.remove(value: 10) + splayTree.remove(value: 6) + + assert(splayTree.value == 2) + } + } From 9da711ddf62bdc9b77d73ad64da8285a94f2b4cc Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:38:47 +0100 Subject: [PATCH 012/528] Fixes for root removal & insertions with nil root --- .../Sources/SplayTree.swift | 106 ++++++++++-------- Splay Tree/SplayTree.swift | 22 +++- 2 files changed, 78 insertions(+), 50 deletions(-) diff --git a/Splay Tree/SplayTree.playground/Sources/SplayTree.swift b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift index f50af7349..a4feda7ef 100644 --- a/Splay Tree/SplayTree.playground/Sources/SplayTree.swift +++ b/Splay Tree/SplayTree.playground/Sources/SplayTree.swift @@ -1,5 +1,5 @@ /* - * Splay Tree + * Splay Tree * * Based on Binary Search Tree Implementation written by Nicolas Ameghino and Matthijs Hollemans for Swift Algorithms Club * https://github.com/raywenderlich/swift-algorithm-club/blob/master/Binary%20Search%20Tree @@ -8,12 +8,12 @@ */ /** - Represent the 3 possible operations (combinations of rotations) that - could be performed during the Splay phase in Splay Trees + Represent the 3 possible operations (combinations of rotations) that + could be performed during the Splay phase in Splay Trees - - zigZag Left child of a right child OR right child of a left child - - zigZig Left child of a left child OR right child of a right child - - zig Only 1 parent and that parent is the root + - zigZag Left child of a right child OR right child of a left child + - zigZig Left child of a left child OR right child of a right child + - zig Only 1 parent and that parent is the root */ public enum SplayOperation { @@ -23,10 +23,10 @@ public enum SplayOperation { /** - Splay the given node up to the root of the tree + Splay the given node up to the root of the tree - - Parameters: - - node SplayTree node to move up to the root + - Parameters: + - node SplayTree node to move up to the root */ public static func splay(node: Node) { @@ -36,13 +36,13 @@ public enum SplayOperation { } /** - Compares the node and its parent and determine - if the rotations should be performed in a zigZag, zigZig or zig case. + Compares the node and its parent and determine + if the rotations should be performed in a zigZag, zigZig or zig case. - - Parmeters: - - forNode SplayTree node to be checked - - Returns - - Operation Case zigZag - zigZig - zig + - Parmeters: + - forNode SplayTree node to be checked + - Returns + - Operation Case zigZag - zigZig - zig */ public static func operation(forNode node: Node) -> SplayOperation { @@ -56,11 +56,11 @@ public enum SplayOperation { } /** - Applies the rotation associated to the case - Modifying the splay tree and briging the received node further to the top of the tree + Applies the rotation associated to the case + Modifying the splay tree and briging the received node further to the top of the tree - - Parameters: - - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent + - Parameters: + - onNode Node to splay up. Should be alwayas the node that needs to be splayed, neither its parent neither it's grandparent */ public func apply(onNode node: Node) { switch self { @@ -68,12 +68,12 @@ public enum SplayOperation { assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") rotate(child: node, parent: node.parent!) rotate(child: node, parent: node.parent!) - + case .zigZig: assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") rotate(child: node.parent!, parent: node.parent!.parent!) rotate(child: node, parent: node.parent!) - + case .zig: assert(node.parent != nil && node.parent!.parent == nil, "There should be a parent which is the root") rotate(child: node, parent: node.parent!) @@ -81,8 +81,8 @@ public enum SplayOperation { } /** - Performs a single rotation from a node to its parent - re-arranging the children properly + Performs a single rotation from a node to its parent + re-arranging the children properly */ public func rotate(child: Node, parent: Node) { @@ -95,41 +95,41 @@ public enum SplayOperation { grandchildToMode = child.right parent.left = grandchildToMode grandchildToMode?.parent = parent - + let grandParent = parent.parent child.parent = grandParent - + if parent.isLeftChild { grandParent?.left = child } else { grandParent?.right = child } - + child.right = parent parent.parent = child - - + + } else { grandchildToMode = child.left parent.right = grandchildToMode grandchildToMode?.parent = parent - + let grandParent = parent.parent child.parent = grandParent - + if parent.isLeftChild { grandParent?.left = child } else { grandParent?.right = child } - + child.left = parent parent.parent = child - + } - + } } @@ -183,13 +183,13 @@ public class Node { } public class SplayTree { - + internal var root: Node? var value: T? { return root?.value } - + //MARK: - Initializer public init(value: T) { @@ -197,13 +197,17 @@ public class SplayTree { } public func insert(value: T) { - root = root?.insert(value: value) + if let root = root { + self.root = root.insert(value: value) + } else { + root = Node(value: value) + } } public func remove(value: T) { root = root?.remove(value: value) } - + public func search(value: T) -> Node? { root = root?.search(value: value) return root @@ -229,10 +233,10 @@ extension Node { Inserts a new element into the node tree. - Parameters: - - value T value to be inserted. Will be splayed to the root position + - value T value to be inserted. Will be splayed to the root position - Returns: - - Node inserted + - Node inserted */ public func insert(value: T) -> Node { if let selfValue = self.value { @@ -275,14 +279,14 @@ extension Node { /* Deletes the given node from the nodes tree. - Return the new tree generated by the removal. + Return the new tree generated by the removal. The removed node (not necessarily the one containing the value), will be splayed to the root. - Parameters: - - value To be removed + - value To be removed - Returns: - - Node Resulting from the deletion and the splaying of the removed node + - Node Resulting from the deletion and the splaying of the removed node */ public func remove(value: T) -> Node? { @@ -302,19 +306,29 @@ extension Node { parentToSplay = replacement.parent - } else { + } else if self.parent != nil { parentToSplay = self.parent + } else { + parentToSplay = replacement } } else { // This node only has a left child. The left child replaces the node. replacement = left - parentToSplay = parent + if self.parent != nil { + parentToSplay = self.parent + } else { + parentToSplay = replacement + } } } else if let right = right { // This node only has a right child. The right child replaces the node. replacement = right - parentToSplay = parent + if self.parent != nil { + parentToSplay = self.parent + } else { + parentToSplay = replacement + } } else { // This node has no children. We just disconnect it from its parent. replacement = nil @@ -332,7 +346,7 @@ extension Node { parent = nil left = nil right = nil - + return parentToSplay } else if let v = self.value, value < v { diff --git a/Splay Tree/SplayTree.swift b/Splay Tree/SplayTree.swift index f50af7349..a7b20743d 100644 --- a/Splay Tree/SplayTree.swift +++ b/Splay Tree/SplayTree.swift @@ -197,7 +197,11 @@ public class SplayTree { } public func insert(value: T) { - root = root?.insert(value: value) + if let root = root { + self.root = root.insert(value: value) + } else { + root = Node(value: value) + } } public func remove(value: T) { @@ -302,19 +306,29 @@ extension Node { parentToSplay = replacement.parent - } else { + } else if self.parent != nil { parentToSplay = self.parent + } else { + parentToSplay = replacement } } else { // This node only has a left child. The left child replaces the node. replacement = left - parentToSplay = parent + if self.parent != nil { + parentToSplay = self.parent + } else { + parentToSplay = replacement + } } } else if let right = right { // This node only has a right child. The right child replaces the node. replacement = right - parentToSplay = parent + if self.parent != nil { + parentToSplay = self.parent + } else { + parentToSplay = replacement + } } else { // This node has no children. We just disconnect it from its parent. replacement = nil From ecba738935641768526277d908153adc3f9d8ca6 Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 5 Mar 2017 19:38:55 +0100 Subject: [PATCH 013/528] Playground Splay Tree --- .../SplayTree.playground/Contents.swift | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Splay Tree/SplayTree.playground/Contents.swift b/Splay Tree/SplayTree.playground/Contents.swift index 951ad4c5c..4406a759d 100644 --- a/Splay Tree/SplayTree.playground/Contents.swift +++ b/Splay Tree/SplayTree.playground/Contents.swift @@ -1,7 +1,29 @@ //: Playground - Splay Tree Implementation -let splayTree = SplayTree(array: [1]) +let splayTree = SplayTree(value: 1) splayTree.insert(value: 2) splayTree.insert(value: 10) splayTree.insert(value: 6) + +splayTree.remove(value: 10) +splayTree.remove(value: 6) + +splayTree.insert(value: 55) +splayTree.insert(value: 559) +splayTree.remove(value: 2) +splayTree.remove(value: 1) +splayTree.remove(value: 55) +splayTree.remove(value: 559) + +splayTree.insert(value: 1843000) +splayTree.insert(value: 1238) +splayTree.insert(value: -1) +splayTree.insert(value: 87) + +splayTree.minimum() +splayTree.maximum() + + + + From 1c43c804633f9fd36e67f9988d17e8402ac258d8 Mon Sep 17 00:00:00 2001 From: Arkalyk Akash Date: Mon, 13 Mar 2017 17:00:42 +0600 Subject: [PATCH 014/528] Egg Drop Dynamic Problem Added --- Egg Drop Problem/EggDrop.swift | 31 +++++++++++++++++++ .../contents.xcworkspacedata | 7 +++++ 2 files changed, 38 insertions(+) create mode 100644 Egg Drop Problem/EggDrop.swift diff --git a/Egg Drop Problem/EggDrop.swift b/Egg Drop Problem/EggDrop.swift new file mode 100644 index 000000000..6d0aab2a1 --- /dev/null +++ b/Egg Drop Problem/EggDrop.swift @@ -0,0 +1,31 @@ +func eggDrop(_ numberOfEggs: Int, numberOfFloors: Int) -> Int { + var eggFloor: [[Int]] = [] //egg(rows) floor(cols) array to store the solutions + var attempts: Int = 0 + + for var i in (0.. k-1 + //case 2: egg doesn't break. meaning we'll still have 'i' number of eggs, and we'll go upstairs -> j-k + attempts = 1 + max(eggFloor[i-1][k-1], eggFloor[i][j-k])//we add one taking into account the attempt we're taking at the moment + + if attempts < eggFloor[i][j]{ //finding the min + eggFloor[i][j] = attempts; + } + } + } + } + + return eggFloor[numberOfEggs][numberOfFloors] +} + +func max(_ x1: Int, _ x2: Int){ + return x1 > x2 ? x1 : x2 +} diff --git a/swift-algorithm-club.xcworkspace/contents.xcworkspacedata b/swift-algorithm-club.xcworkspace/contents.xcworkspacedata index b2ffce836..5ac8577f5 100644 --- a/swift-algorithm-club.xcworkspace/contents.xcworkspacedata +++ b/swift-algorithm-club.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,13 @@ + + + + From f536ff10804f32066a5fdea1becfc6b80ebbf25f Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 02:06:55 +0600 Subject: [PATCH 015/528] Bugs fied. Readme added. --- .../EggDrop.playground/Contents.swift | 5 +++ .../EggDrop.playground/Sources/EggDrop.swift | 41 +++++++++++++++++ .../EggDrop.playground/contents.xcplayground | 4 ++ Egg Drop Problem/EggDrop.swift | 36 +++++++++------ Egg Drop Problem/README.markdown | 44 +++++++++++++++++++ .../contents.xcworkspacedata | 6 +++ 6 files changed, 123 insertions(+), 13 deletions(-) create mode 100644 Egg Drop Problem/EggDrop.playground/Contents.swift create mode 100644 Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift create mode 100644 Egg Drop Problem/EggDrop.playground/contents.xcplayground create mode 100644 Egg Drop Problem/README.markdown diff --git a/Egg Drop Problem/EggDrop.playground/Contents.swift b/Egg Drop Problem/EggDrop.playground/Contents.swift new file mode 100644 index 000000000..4ddb936b3 --- /dev/null +++ b/Egg Drop Problem/EggDrop.playground/Contents.swift @@ -0,0 +1,5 @@ + //: Playground - noun: a place where people can play + +import Cocoa + +eggDrop(numberOfEggs: 2, numberOfFloors: 4) diff --git a/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift new file mode 100644 index 000000000..f69284491 --- /dev/null +++ b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift @@ -0,0 +1,41 @@ +public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { + if numberOfEggs == 0 || numberOfFloors == 0{ + return 0 + } + if numberOfEggs == 1 || numberOfFloors == 1{ + return 1 + } + + var eggFloor = [[Int]](repeating: [Int](repeating: 0, count: numberOfFloors+1), count: numberOfEggs+1) //egg(rows) floor(cols) array to store the solutions + var attempts: Int = 0 + + for var floorNumber in (0..<(numberOfFloors+1)){ + eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts + for var eggNumber in (2..<(numberOfEggs+1)){ + eggFloor[eggNumber][floorNumber] = 0 + } + } + eggFloor[2][1] = 1 //base case: if there's are two eggs and one floor, it takes one attempt + + for var eggNumber in (2..<(numberOfEggs+1)){ + for var floorNumber in (2..<(numberOfFloors+1)){ + eggFloor[eggNumber][floorNumber] = 1000000 + for var visitingFloor in (1..<(floorNumber+1)){ + //there are two cases + //case 1: egg breaks. meaning we'll have one less egg, and we'll have to go downstairs -> visitingFloor-1 + //case 2: egg doesn't break. meaning we'll still have 'eggs' number of eggs, and we'll go upstairs -> floorNumber-visitingFloor + attempts = 1 + max(eggFloor[eggNumber-1][visitingFloor-1], eggFloor[eggNumber][floorNumber-visitingFloor])//we add one taking into account the attempt we're taking at the moment + + if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min + eggFloor[eggNumber][floorNumber] = attempts; + } + } + } + } + + return eggFloor[numberOfEggs][numberOfFloors] +} + +public func max(_ x1: Int, _ x2: Int) -> Int{ + return x1 > x2 ? x1 : x2 +} diff --git a/Egg Drop Problem/EggDrop.playground/contents.xcplayground b/Egg Drop Problem/EggDrop.playground/contents.xcplayground new file mode 100644 index 000000000..63b6dd8df --- /dev/null +++ b/Egg Drop Problem/EggDrop.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Egg Drop Problem/EggDrop.swift b/Egg Drop Problem/EggDrop.swift index 6d0aab2a1..a525793db 100644 --- a/Egg Drop Problem/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.swift @@ -1,23 +1,33 @@ -func eggDrop(_ numberOfEggs: Int, numberOfFloors: Int) -> Int { - var eggFloor: [[Int]] = [] //egg(rows) floor(cols) array to store the solutions +public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { + if numberOfEggs == 0 || numberOfFloors == 0{ + return 0 + } + if numberOfEggs == 1 || numberOfFloors == 1{ + return 1 + } + + var eggFloor = [[Int]](repeating: [Int](repeating: 0, count: numberOfFloors+1), count: numberOfEggs+1) //egg(rows) floor(cols) array to store the solutions var attempts: Int = 0 - for var i in (0.. k-1 - //case 2: egg doesn't break. meaning we'll still have 'i' number of eggs, and we'll go upstairs -> j-k - attempts = 1 + max(eggFloor[i-1][k-1], eggFloor[i][j-k])//we add one taking into account the attempt we're taking at the moment + //case 2: egg doesn't break. meaning we'll still have 'eggs' number of eggs, and we'll go upstairs -> floors-k + attempts = 1 + max(eggFloor[eggNumber-1][floors-1], eggFloor[eggNumber][floorNumber-floors])//we add one taking into account the attempt we're taking at the moment - if attempts < eggFloor[i][j]{ //finding the min - eggFloor[i][j] = attempts; + if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min + eggFloor[eggNumber][floorNumber] = attempts; } } } @@ -26,6 +36,6 @@ func eggDrop(_ numberOfEggs: Int, numberOfFloors: Int) -> Int { return eggFloor[numberOfEggs][numberOfFloors] } -func max(_ x1: Int, _ x2: Int){ +public func max(_ x1: Int, _ x2: Int) -> Int{ return x1 > x2 ? x1 : x2 } diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown new file mode 100644 index 000000000..a58827ba3 --- /dev/null +++ b/Egg Drop Problem/README.markdown @@ -0,0 +1,44 @@ +#Egg Drop Dynamic Problem + +#Problem Description + +Given some number of floors and some number of eggs, what is the minimum number of attempts it will take to find out from which floor egg will break. + +Suppose that we wish to know which stories in a 36-story building are safe to drop eggs from, and which will cause the eggs to break on landing. We make a few assumptions: + +- An egg that survives a fall can be used again. +- A broken egg must be discarded. +- The effect of a fall is the same for all eggs. +- If an egg breaks when dropped, then it would break if dropped from a higher floor. +- If an egg survives a fall then it would survive a shorter fall. + +If only one egg is available and we wish to be sure of obtaining the right result, the experiment can be carried out in only one way. Drop the egg from the first-floor window; if it survives, drop it from the second floor window. Continue upward until it breaks. In the worst case, this method may require 36 droppings. Suppose 2 eggs are available. What is the least number of egg-droppings that is guaranteed to work in all cases? +The problem is not actually to find the critical floor, but merely to decide floors from which eggs should be dropped so that total number of trials are minimized. + +#Solution +We store all the solutions in a 2D array. Where rows represents number of eggs and columns represent number of floors. + +First, we set base cases: +1) If there's only one egg, it takes as many attempts as number of floors +2) If there's are two eggs and one floor, it takes one attempt + +eggNumber ==> Number of eggs at the moment +floorNumber ==> Floor number at the moment +visitingFloor ==> Floor being visited at the moment +attempts ==> Minimum number of attempts it will take to find out from which floor egg will break + +When we drop an egg from a floor 'floorNumber', there can be two cases (1) The egg breaks (2) The egg doesn’t break. + +1) If the egg breaks after dropping from 'floorNumberth' floor, then we only need to check for floors lower than 'floorNumber' with remaining eggs; so the problem reduces to 'floorNumber'-1 floors and 'eggNumber'-1 eggs +2) If the egg doesn’t break after dropping from the xth floor, then we only need to check for floors higher than 'floorNumber'; so the problem reduces to floors-'floorNumber' floors and 'eggNumber' eggs. + +Since we need to minimize the number of trials in worst case, we take the maximum of two cases. We consider the max of above two cases for every floor and choose the floor which yields minimum number of trials. + +```swift + +attempts = 1 + max(eggFloor[eggNumber-1][floors-1], eggFloor[eggNumber][floorNumber-floors])//we add one taking into account the attempt we're taking at the moment + +if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min + eggFloor[eggNumber][floorNumber] = attempts; +} +``` diff --git a/swift-algorithm-club.xcworkspace/contents.xcworkspacedata b/swift-algorithm-club.xcworkspace/contents.xcworkspacedata index 5ac8577f5..1c6b407c3 100644 --- a/swift-algorithm-club.xcworkspace/contents.xcworkspacedata +++ b/swift-algorithm-club.xcworkspace/contents.xcworkspacedata @@ -7,6 +7,12 @@ + + + + From 75d3b5b59977a1cc54bcac2ce42e2c884eab5e69 Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 02:12:30 +0600 Subject: [PATCH 016/528] Bugs fixed --- Egg Drop Problem/README.markdown | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index a58827ba3..44af8174a 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -23,19 +23,21 @@ First, we set base cases: 2) If there's are two eggs and one floor, it takes one attempt eggNumber ==> Number of eggs at the moment + floorNumber ==> Floor number at the moment + visitingFloor ==> Floor being visited at the moment + attempts ==> Minimum number of attempts it will take to find out from which floor egg will break When we drop an egg from a floor 'floorNumber', there can be two cases (1) The egg breaks (2) The egg doesn’t break. -1) If the egg breaks after dropping from 'floorNumberth' floor, then we only need to check for floors lower than 'floorNumber' with remaining eggs; so the problem reduces to 'floorNumber'-1 floors and 'eggNumber'-1 eggs -2) If the egg doesn’t break after dropping from the xth floor, then we only need to check for floors higher than 'floorNumber'; so the problem reduces to floors-'floorNumber' floors and 'eggNumber' eggs. +1) If the egg breaks after dropping from 'visitingFloorth' floor, then we only need to check for floors lower than 'visitingFloor' with remaining eggs; so the problem reduces to 'visitingFloor'-1 floors and 'eggNumber'-1 eggs. +2) If the egg doesn’t break after dropping from the 'visitingFloorth' floor, then we only need to check for floors higher than 'visitingFloor'; so the problem reduces to floors-'visitingFloor' floors and 'eggNumber' eggs. Since we need to minimize the number of trials in worst case, we take the maximum of two cases. We consider the max of above two cases for every floor and choose the floor which yields minimum number of trials. ```swift - attempts = 1 + max(eggFloor[eggNumber-1][floors-1], eggFloor[eggNumber][floorNumber-floors])//we add one taking into account the attempt we're taking at the moment if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min From 61949ab24314ee060f888642c59d6d20bcfa4841 Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 11:09:53 +0600 Subject: [PATCH 017/528] Minor changes in README --- .../EggDrop.playground/Sources/EggDrop.swift | 9 +++------ Egg Drop Problem/EggDrop.swift | 16 ++++++++-------- Egg Drop Problem/README.markdown | 19 ++++++++++++------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift index f69284491..897ba2dee 100644 --- a/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift @@ -1,5 +1,5 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { - if numberOfEggs == 0 || numberOfFloors == 0{ + if numberOfEggs == 0 || numberOfFloors == 0{ //edge case: When either number of eggs or number of floors is 0, answer is 0 return 0 } if numberOfEggs == 1 || numberOfFloors == 1{ @@ -11,15 +11,12 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { for var floorNumber in (0..<(numberOfFloors+1)){ eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts - for var eggNumber in (2..<(numberOfEggs+1)){ - eggFloor[eggNumber][floorNumber] = 0 - } } - eggFloor[2][1] = 1 //base case: if there's are two eggs and one floor, it takes one attempt + eggFloor[2][1] = 1 //base case: if there are two eggs and one floor, it takes one attempt for var eggNumber in (2..<(numberOfEggs+1)){ for var floorNumber in (2..<(numberOfFloors+1)){ - eggFloor[eggNumber][floorNumber] = 1000000 + eggFloor[eggNumber][floorNumber] = Int.max //setting the final result a high number to find out minimum for var visitingFloor in (1..<(floorNumber+1)){ //there are two cases //case 1: egg breaks. meaning we'll have one less egg, and we'll have to go downstairs -> visitingFloor-1 diff --git a/Egg Drop Problem/EggDrop.swift b/Egg Drop Problem/EggDrop.swift index a525793db..7be691f57 100644 --- a/Egg Drop Problem/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.swift @@ -1,5 +1,5 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { - if numberOfEggs == 0 || numberOfFloors == 0{ + if numberOfEggs == 0 || numberOfFloors == 0{ //edge case: When either number of eggs or number of floors is 0, answer is 0 return 0 } if numberOfEggs == 1 || numberOfFloors == 1{ @@ -10,21 +10,21 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { var attempts: Int = 0 for var floorNumber in (0..<(numberOfFloors+1)){ - eggFloor[1][floorNumber] = floorNumber + eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts for var eggNumber in (2..<(numberOfEggs+1)){ eggFloor[eggNumber][floorNumber] = 0 } } - eggFloor[2][1] = 1 + eggFloor[2][1] = 1 //base case: if there are two eggs and one floor, it takes one attempt for var eggNumber in (2..<(numberOfEggs+1)){ for var floorNumber in (2..<(numberOfFloors+1)){ - eggFloor[eggNumber][floorNumber] = 1000000 - for var floors in (1..<(floorNumber+1)){ + eggFloor[eggNumber][floorNumber] = Int.max //setting the final result a high number to find out minimum + for var visitingFloor in (1..<(floorNumber+1)){ //there are two cases - //case 1: egg breaks. meaning we'll have one less egg, and we'll have to go downstairs -> k-1 - //case 2: egg doesn't break. meaning we'll still have 'eggs' number of eggs, and we'll go upstairs -> floors-k - attempts = 1 + max(eggFloor[eggNumber-1][floors-1], eggFloor[eggNumber][floorNumber-floors])//we add one taking into account the attempt we're taking at the moment + //case 1: egg breaks. meaning we'll have one less egg, and we'll have to go downstairs -> visitingFloor-1 + //case 2: egg doesn't break. meaning we'll still have 'eggs' number of eggs, and we'll go upstairs -> floorNumber-visitingFloor + attempts = 1 + max(eggFloor[eggNumber-1][visitingFloor-1], eggFloor[eggNumber][floorNumber-visitingFloor])//we add one taking into account the attempt we're taking at the moment if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min eggFloor[eggNumber][floorNumber] = attempts; diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index 44af8174a..2df3088b5 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -22,19 +22,24 @@ First, we set base cases: 1) If there's only one egg, it takes as many attempts as number of floors 2) If there's are two eggs and one floor, it takes one attempt -eggNumber ==> Number of eggs at the moment - -floorNumber ==> Floor number at the moment - -visitingFloor ==> Floor being visited at the moment - -attempts ==> Minimum number of attempts it will take to find out from which floor egg will break +- eggNumber ==> Number of eggs at the moment +- floorNumber ==> Floor number at the moment +- visitingFloor ==> Floor being visited at the moment +- attempts ==> Minimum number of attempts it will take to find out from which floor egg will break When we drop an egg from a floor 'floorNumber', there can be two cases (1) The egg breaks (2) The egg doesn’t break. 1) If the egg breaks after dropping from 'visitingFloorth' floor, then we only need to check for floors lower than 'visitingFloor' with remaining eggs; so the problem reduces to 'visitingFloor'-1 floors and 'eggNumber'-1 eggs. 2) If the egg doesn’t break after dropping from the 'visitingFloorth' floor, then we only need to check for floors higher than 'visitingFloor'; so the problem reduces to floors-'visitingFloor' floors and 'eggNumber' eggs. +```swift +for var floorNumber in (0..<(numberOfFloors+1)){ + eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts +} + +eggFloor[2][1] = 1 //base case: if there are two eggs and one floor, it takes one attempt +``` + Since we need to minimize the number of trials in worst case, we take the maximum of two cases. We consider the max of above two cases for every floor and choose the floor which yields minimum number of trials. ```swift From 4ab987c592763cd13719411b829d8d513a64707b Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 11:14:18 +0600 Subject: [PATCH 018/528] Minor changes in README --- Egg Drop Problem/README.markdown | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index 2df3088b5..eda28fa6f 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -16,32 +16,33 @@ If only one egg is available and we wish to be sure of obtaining the right resul The problem is not actually to find the critical floor, but merely to decide floors from which eggs should be dropped so that total number of trials are minimized. #Solution +- eggNumber -> Number of eggs at the moment +- floorNumber -> Floor number at the moment +- visitingFloor -> Floor being visited at the moment +- attempts -> Minimum number of attempts it will take to find out from which floor egg will break + We store all the solutions in a 2D array. Where rows represents number of eggs and columns represent number of floors. First, we set base cases: 1) If there's only one egg, it takes as many attempts as number of floors 2) If there's are two eggs and one floor, it takes one attempt -- eggNumber ==> Number of eggs at the moment -- floorNumber ==> Floor number at the moment -- visitingFloor ==> Floor being visited at the moment -- attempts ==> Minimum number of attempts it will take to find out from which floor egg will break - -When we drop an egg from a floor 'floorNumber', there can be two cases (1) The egg breaks (2) The egg doesn’t break. - -1) If the egg breaks after dropping from 'visitingFloorth' floor, then we only need to check for floors lower than 'visitingFloor' with remaining eggs; so the problem reduces to 'visitingFloor'-1 floors and 'eggNumber'-1 eggs. -2) If the egg doesn’t break after dropping from the 'visitingFloorth' floor, then we only need to check for floors higher than 'visitingFloor'; so the problem reduces to floors-'visitingFloor' floors and 'eggNumber' eggs. - ```swift for var floorNumber in (0..<(numberOfFloors+1)){ - eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts +eggFloor[1][floorNumber] = floorNumber //base case 1: if there's only one egg, it takes 'numberOfFloors' attempts } -eggFloor[2][1] = 1 //base case: if there are two eggs and one floor, it takes one attempt +eggFloor[2][1] = 1 //base case 2: if there are two eggs and one floor, it takes one attempt ``` +When we drop an egg from a floor 'floorNumber', there can be two cases (1) The egg breaks (2) The egg doesn’t break. + +1) If the egg breaks after dropping from 'visitingFloorth' floor, then we only need to check for floors lower than 'visitingFloor' with remaining eggs; so the problem reduces to 'visitingFloor'-1 floors and 'eggNumber'-1 eggs. +2) If the egg doesn’t break after dropping from the 'visitingFloorth' floor, then we only need to check for floors higher than 'visitingFloor'; so the problem reduces to floors-'visitingFloor' floors and 'eggNumber' eggs. + Since we need to minimize the number of trials in worst case, we take the maximum of two cases. We consider the max of above two cases for every floor and choose the floor which yields minimum number of trials. +We find the answer based on the base cases and previously found answers as follows. ```swift attempts = 1 + max(eggFloor[eggNumber-1][floors-1], eggFloor[eggNumber][floorNumber-floors])//we add one taking into account the attempt we're taking at the moment From 1fbb40efe14b80d6187a9ebd698960ba3520fe3b Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 11:35:40 +0600 Subject: [PATCH 019/528] Example added --- Egg Drop Problem/EggDrop.playground/Contents.swift | 6 +++++- Egg Drop Problem/EggDrop.swift | 3 --- Egg Drop Problem/README.markdown | 14 +++++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Egg Drop Problem/EggDrop.playground/Contents.swift b/Egg Drop Problem/EggDrop.playground/Contents.swift index 4ddb936b3..d452e7f9f 100644 --- a/Egg Drop Problem/EggDrop.playground/Contents.swift +++ b/Egg Drop Problem/EggDrop.playground/Contents.swift @@ -2,4 +2,8 @@ import Cocoa -eggDrop(numberOfEggs: 2, numberOfFloors: 4) +eggDrop(numberOfEggs: 2, numberOfFloors: 2) //expected answer: 2 +eggDrop(numberOfEggs: 2, numberOfFloors: 4) //expected answer: 3 +eggDrop(numberOfEggs: 2, numberOfFloors: 6) //expected answer: 3 +eggDrop(numberOfEggs: 5, numberOfFloors: 5) //expected answer: 2 +eggDrop(numberOfEggs: 5, numberOfFloors: 20) //expected answer: 4 \ No newline at end of file diff --git a/Egg Drop Problem/EggDrop.swift b/Egg Drop Problem/EggDrop.swift index 7be691f57..897ba2dee 100644 --- a/Egg Drop Problem/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.swift @@ -11,9 +11,6 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { for var floorNumber in (0..<(numberOfFloors+1)){ eggFloor[1][floorNumber] = floorNumber //base case: if there's only one egg, it takes 'numberOfFloors' attempts - for var eggNumber in (2..<(numberOfEggs+1)){ - eggFloor[eggNumber][floorNumber] = 0 - } } eggFloor[2][1] = 1 //base case: if there are two eggs and one floor, it takes one attempt diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index eda28fa6f..1a436c374 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -25,7 +25,7 @@ We store all the solutions in a 2D array. Where rows represents number of eggs a First, we set base cases: 1) If there's only one egg, it takes as many attempts as number of floors -2) If there's are two eggs and one floor, it takes one attempt +2) If there are two eggs and one floor, it takes one attempt ```swift for var floorNumber in (0..<(numberOfFloors+1)){ @@ -50,3 +50,15 @@ if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min eggFloor[eggNumber][floorNumber] = attempts; } ``` +Example: +Let's assume we have 2 eggs and 2 floors. +1) We drop one egg from the first floor. If it breaks, then we get the answer. If it doesn't we'll have 2 eggs and 1 floors to work with. + attempts = 1 + maximum of 0(got the answer) and eggFloor[2][1] (base case 2 which gives us 1) + attempts = 1 + 1 = 2 +2) We drop one egg from the second floor. If it breaks, we'll have 1 egg and 1 floors to work with. If it doesn't, we'll get the answer. + attempts = 1 + maximum of eggFloor[1][1](base case 1 which gives us 1) and 0(got the answer) + attempts = 1 + 1 = 2 +3) Finding the minimum of 2 and 2 gives us 2, so the answer is 2. + 2 is the minimum number of attempts it will take to find out from which floor egg will break. + + From 082385a5ac58967b8eaf565654f1620444383ebf Mon Sep 17 00:00:00 2001 From: Arkalyk Akash Date: Sat, 15 Apr 2017 11:37:09 +0600 Subject: [PATCH 020/528] Update README.markdown --- Egg Drop Problem/README.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index 1a436c374..5ff6ebb1d 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -1,6 +1,6 @@ -#Egg Drop Dynamic Problem +# Egg Drop Dynamic Problem -#Problem Description +# Problem Description Given some number of floors and some number of eggs, what is the minimum number of attempts it will take to find out from which floor egg will break. @@ -15,7 +15,7 @@ Suppose that we wish to know which stories in a 36-story building are safe to dr If only one egg is available and we wish to be sure of obtaining the right result, the experiment can be carried out in only one way. Drop the egg from the first-floor window; if it survives, drop it from the second floor window. Continue upward until it breaks. In the worst case, this method may require 36 droppings. Suppose 2 eggs are available. What is the least number of egg-droppings that is guaranteed to work in all cases? The problem is not actually to find the critical floor, but merely to decide floors from which eggs should be dropped so that total number of trials are minimized. -#Solution +# Solution - eggNumber -> Number of eggs at the moment - floorNumber -> Floor number at the moment - visitingFloor -> Floor being visited at the moment From ffea424eec7b80d010d731f6f1b44c442c26cab8 Mon Sep 17 00:00:00 2001 From: Arkalyk Akash Date: Sat, 15 Apr 2017 11:37:55 +0600 Subject: [PATCH 021/528] Update README.markdown --- Egg Drop Problem/README.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Egg Drop Problem/README.markdown b/Egg Drop Problem/README.markdown index 5ff6ebb1d..82543502d 100644 --- a/Egg Drop Problem/README.markdown +++ b/Egg Drop Problem/README.markdown @@ -1,6 +1,6 @@ # Egg Drop Dynamic Problem -# Problem Description +## Problem Description Given some number of floors and some number of eggs, what is the minimum number of attempts it will take to find out from which floor egg will break. @@ -15,7 +15,7 @@ Suppose that we wish to know which stories in a 36-story building are safe to dr If only one egg is available and we wish to be sure of obtaining the right result, the experiment can be carried out in only one way. Drop the egg from the first-floor window; if it survives, drop it from the second floor window. Continue upward until it breaks. In the worst case, this method may require 36 droppings. Suppose 2 eggs are available. What is the least number of egg-droppings that is guaranteed to work in all cases? The problem is not actually to find the critical floor, but merely to decide floors from which eggs should be dropped so that total number of trials are minimized. -# Solution +## Solution - eggNumber -> Number of eggs at the moment - floorNumber -> Floor number at the moment - visitingFloor -> Floor being visited at the moment @@ -50,7 +50,7 @@ if attempts < eggFloor[eggNumber][floorNumber]{ //finding the min eggFloor[eggNumber][floorNumber] = attempts; } ``` -Example: +## Example Let's assume we have 2 eggs and 2 floors. 1) We drop one egg from the first floor. If it breaks, then we get the answer. If it doesn't we'll have 2 eggs and 1 floors to work with. attempts = 1 + maximum of 0(got the answer) and eggFloor[2][1] (base case 2 which gives us 1) From 260948a2b7af625ea0fe6590e3cf966975c420dd Mon Sep 17 00:00:00 2001 From: ARKALYK AKASH Date: Sat, 15 Apr 2017 11:41:32 +0600 Subject: [PATCH 022/528] Comments added --- Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift | 3 ++- Egg Drop Problem/EggDrop.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift index 897ba2dee..db1e48b95 100644 --- a/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.playground/Sources/EggDrop.swift @@ -2,7 +2,7 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { if numberOfEggs == 0 || numberOfFloors == 0{ //edge case: When either number of eggs or number of floors is 0, answer is 0 return 0 } - if numberOfEggs == 1 || numberOfFloors == 1{ + if numberOfEggs == 1 || numberOfFloors == 1{ //edge case: When either number of eggs or number of floors is 1, answer is 1 return 1 } @@ -33,6 +33,7 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { return eggFloor[numberOfEggs][numberOfFloors] } +//Helper function to find max of two integers public func max(_ x1: Int, _ x2: Int) -> Int{ return x1 > x2 ? x1 : x2 } diff --git a/Egg Drop Problem/EggDrop.swift b/Egg Drop Problem/EggDrop.swift index 897ba2dee..db1e48b95 100644 --- a/Egg Drop Problem/EggDrop.swift +++ b/Egg Drop Problem/EggDrop.swift @@ -2,7 +2,7 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { if numberOfEggs == 0 || numberOfFloors == 0{ //edge case: When either number of eggs or number of floors is 0, answer is 0 return 0 } - if numberOfEggs == 1 || numberOfFloors == 1{ + if numberOfEggs == 1 || numberOfFloors == 1{ //edge case: When either number of eggs or number of floors is 1, answer is 1 return 1 } @@ -33,6 +33,7 @@ public func eggDrop(numberOfEggs: Int, numberOfFloors: Int) -> Int { return eggFloor[numberOfEggs][numberOfFloors] } +//Helper function to find max of two integers public func max(_ x1: Int, _ x2: Int) -> Int{ return x1 > x2 ? x1 : x2 } From d2f02efd49d2367382c7a6fffc5fa1e3b74c8eff Mon Sep 17 00:00:00 2001 From: Barbara Martina Rodeker Date: Sun, 21 May 2017 21:46:01 +0200 Subject: [PATCH 023/528] Initial Docs template and text --- Splay Tree/readme.md | 61 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/Splay Tree/readme.md b/Splay Tree/readme.md index 2282502fa..aa6bdd4db 100644 --- a/Splay Tree/readme.md +++ b/Splay Tree/readme.md @@ -1 +1,60 @@ -In progress +# Splay Tree +Splay tree is a data structure, structurally identitical to a Balanced Binary Search Tree. Every operation performed on a Splay Tree causes a readjustment in order to provide fast access to recently operated values. On every access, the tree is rearranged and the node accessed is moved to the root of the tree using a set of specific rotations, which together are referred to as **Splaying**. + + +## Rotations + +### Zig-Zig + +Given a node *a* if *a* is not the root, and *a* has a child *b*, and both *a* and *b* are left children or right children, a **Zig-Zig** is performed. + +### Zig-Zag + +Given a node *a* if *a* is not the root, and *a* has a child *b*, and *b* is the left child of *a* being the right child (or the opporsite), a **Zig-Zag** is performed. + +### Zig + +A **Zig** is performed when the node *a* to be rotated has the root as parent. + +## Splaying + +## Operations + +### Insertion + +### Deletion + +### Search + +## Examples + +### Example 1 + +### Example 2 + +### Example 3 + +## Advantages + +Splay trees provide an efficient way to quickly access elements that are frequently requested. This characteristic makes then a good choice to implement, for exmaple, caches or garbage collection algorithms, or in any other problem involving frequent access to a certain numbers of elements from a data set. + +## Disadvantages + +Splay tree are not perfectly balanced always, so in case of accessing all the elements in the tree in an increasing order, the height of the tree becomes *n*. + +## Time complexity + +| Case | Performance | +| ------------- |:-------------:| +| Average | O(log n) | +| Worst | n | + +With *n* being the number of items in the tree. + + +## See also + +[Splay Tree on Wikipedia](https://en.wikipedia.org/wiki/Splay_tree) +[Splay Tree by University of California in Berkeley - CS 61B Lecture 34](https://www.youtube.com/watch?v=G5QIXywcJlY) + +*Written for Swift Algorithm Club by Mike Taghavi and Matthijs Hollemans* From 7f751918b92881d93aabce634a891b95f46a90f0 Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 21 May 2017 22:03:23 +0200 Subject: [PATCH 024/528] images for documentation --- Splay Tree/Images /zig.png | Bin 0 -> 7793 bytes Splay Tree/Images /zigzag1.png | Bin 0 -> 13964 bytes Splay Tree/Images /zigzag2.png | Bin 0 -> 13877 bytes Splay Tree/Images /zigzig1.png | Bin 0 -> 13855 bytes Splay Tree/Images /zigzig2.png | Bin 0 -> 15179 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Splay Tree/Images /zig.png create mode 100644 Splay Tree/Images /zigzag1.png create mode 100644 Splay Tree/Images /zigzag2.png create mode 100644 Splay Tree/Images /zigzig1.png create mode 100644 Splay Tree/Images /zigzig2.png diff --git a/Splay Tree/Images /zig.png b/Splay Tree/Images /zig.png new file mode 100644 index 0000000000000000000000000000000000000000..e21522b6fe55f9529b2f818a4e108cd47964908b GIT binary patch literal 7793 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 YUzYE4d4Gxltz?jjlBQyfyhZr`0hMWjJpcdz literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /zigzag1.png b/Splay Tree/Images /zigzag1.png new file mode 100644 index 0000000000000000000000000000000000000000..1bd40624802f9bbafa93472c6d3b8ec37711d0bc GIT binary patch literal 13964 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 W8y_a@5`1NbBL7lJrbNov@BaW;q?*+L literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /zigzag2.png b/Splay Tree/Images /zigzag2.png new file mode 100644 index 0000000000000000000000000000000000000000..5f8e4c63f9763560028d3088396d3e24b5787b4a GIT binary patch literal 13877 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 literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /zigzig1.png b/Splay Tree/Images /zigzig1.png new file mode 100644 index 0000000000000000000000000000000000000000..11ec330f2a33a56b5cb2aa983f05d7b9ed7b97c1 GIT binary patch literal 13855 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 LH5H2GUikfg>;GAg literal 0 HcmV?d00001 From 6c1c12651247ed73e3e727c0e7dc28e2a0b1e518 Mon Sep 17 00:00:00 2001 From: barbara Date: Sun, 21 May 2017 22:17:44 +0200 Subject: [PATCH 025/528] Images for examples documentation --- Splay Tree/Images /example1-1.png | Bin 0 -> 13964 bytes Splay Tree/Images /example1-2.png | Bin 0 -> 15451 bytes Splay Tree/Images /example1-3.png | Bin 0 -> 14778 bytes Splay Tree/Images /examplezig.svg | 2 ++ Splay Tree/Images /examplezig1.png | Bin 0 -> 6583 bytes Splay Tree/Images /examplezig2.png | Bin 0 -> 9317 bytes Splay Tree/Images /examplezigzig.svg | 2 ++ Splay Tree/Images /examplezigzig1.png | Bin 0 -> 13855 bytes Splay Tree/Images /examplezigzig2.png | Bin 0 -> 15247 bytes Splay Tree/Images /examplezigzig3.png | Bin 0 -> 18128 bytes 10 files changed, 4 insertions(+) create mode 100644 Splay Tree/Images /example1-1.png create mode 100644 Splay Tree/Images /example1-2.png create mode 100644 Splay Tree/Images /example1-3.png create mode 100644 Splay Tree/Images /examplezig.svg create mode 100644 Splay Tree/Images /examplezig1.png create mode 100644 Splay Tree/Images /examplezig2.png create mode 100644 Splay Tree/Images /examplezigzig.svg create mode 100644 Splay Tree/Images /examplezigzig1.png create mode 100644 Splay Tree/Images /examplezigzig2.png create mode 100644 Splay Tree/Images /examplezigzig3.png diff --git a/Splay Tree/Images /example1-1.png b/Splay Tree/Images /example1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1bd40624802f9bbafa93472c6d3b8ec37711d0bc GIT binary patch literal 13964 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 W8y_a@5`1NbBL7lJrbNov@BaW;q?*+L literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /example1-2.png b/Splay Tree/Images /example1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..46dd35bcd131dc43f7edb45a9efe7c6c585950f0 GIT binary patch literal 15451 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 TFbIB=iK8U1CRZY38t{JrK7T3H literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /examplezig.svg b/Splay Tree/Images /examplezig.svg new file mode 100644 index 000000000..800ef1886 --- /dev/null +++ b/Splay Tree/Images /examplezig.svg @@ -0,0 +1,2 @@ + +
2
2
6
6
10
10
2
2
6
6
10
10
\ No newline at end of file diff --git a/Splay Tree/Images /examplezig1.png b/Splay Tree/Images /examplezig1.png new file mode 100644 index 0000000000000000000000000000000000000000..dda9d6de91d4dcd011fcc9356ee305a8c0eb68e1 GIT binary patch literal 6583 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 U21jw=A2I}Y(05T)YIYI-53Dwf-2eap literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /examplezig2.png b/Splay Tree/Images /examplezig2.png new file mode 100644 index 0000000000000000000000000000000000000000..ba8a48867103c53ac775bd74046d239deaf747eb GIT binary patch literal 9317 zcmZvicQ{<{`tFBJ7^2MRQO8UOg6O>)CHgQ*^d3D*^j?Bd1_@E33nn9p5JI#dIuU{> ziC%(;7D;qx*?a%KzkRNA{^GjUnwhoU^*+yYf9`u>4fHf9$(hMPAQ0spO_U+fUACdm4y6{$D<j-ya zkVHf%#w$7ON(c5I3{Xl?2vM9WmIg-6gmrGBLny1L@Kj`Xz|W4qH?OrqN-7(wx3*_z z{ha6IJbupY&z`h4hwezv@AVH13?L-b+q)q7@}W;YkBx1-zc{Nt{MO|EBXuWD@jS=S z(2z$+D4m#?xGV5aq$vS|b(Y&C=z5HUm0vW9Sk1sEc-RhU^bMbkq!}Nsc_SVq9>+R83VscLY?o{e4 z9Chiv*k2tCwOmbQk=*K13^~B_G&}U-#!FO5_y7L=+ZcB5st~$>vnw*2IXZ!w<8v35 zcH>}U4D-@lTsE4Vfgf+)9C^HP^MtxH>y|0rYqqJ*wu6`tT^i@+FM>9XeR9o&CA$Cd z&9Rw!_p5i}sn`es{#1h+EV~Xc7);r3Z3tb?rh_rIT~(Pt*)DcI6m$K2BTqK))!~!w zk;09!%480l&vH+2{aqbQb!Y#>=h*hOk565fMYRnmSPa*Cg8Rc!J-0&1y}Fb*@OnF3!>`N{o(< zj#ru9&Tj5P`Ck`lQ}zU#yf9Pl@9(E$VW|o*&da`-zE^~P%&qIvl?W4@_=xf+6Kpf{ z1S@^k&KAV}Lcd`i4qKExUCp-P+eXkD3uD4cW*`ebj0#Q8mUsN@6SC_4z7HpH#OC7N zJ}C&=z=)@$HpeQ{T<7j&Jz!?hZVue3SXi*F%oar#sB|&9M1%4fUoiOOW@IRcrzuxSFtbwmvLz6dv=8S*RKS{cNy;W<+${7f{~ z6a=R!)P@v%ZS*PofXKzqsXQI@xlW`rQe|3AVDMS;jeXEU)Nys9$~5pWwi`9!@O0*8`c&XQ8AZ`WXq-lQNokU-jecMI^{hJy5>Te`ODYxU(Cw)Tk{kuK) z{%lQypJ!LM9dD*`?W({^Ro5vQwx(J*Wn7%XzE+6dkYK0Q~Iyg>r%&1aNSVRvBp`@h0 zS0&-3YK;yaaES*!h@+vQfe=VNf{~#2-~aslY6R@E?uR;L=4E0L94je64Ij-A{$`4yAcc z2B{;|UAaA7T_YW_q^Tp8yfag^PTHMllVk>g!%@>DSd9`=9mmRRsMlEPW=mwYzqJI^ zHLrkxE}m&$mN0QIR{bn;r}gjp$qi7jqeb>u&m)^w&7_Lhj@@J=m~+f6&Vj`7BrTUQ)Z~X{3~MA2g;R;w(f< zOUu4gh6Qup{2fx~K8Zshk2QzlE}P^?I1yiG1FEN8gX2Z?`O+mp(Yyo_{_ zTHHDG$yg*?0NP%i^GD#b z`65B_G`d)hs6k#cd+9x=6QPn*klrp@2P3c1f$*1f|H6MuSQwpmupo_WBVN@wk5~NlA?QDdIGcUR_;H_tEjw4c_<;=2Tl7 zo4>ue;o-BrxSa-$BaB)LwxgV)p~J;>fpmey-n#3k2u-vsEEf)<$8t z0Y7D0a7;`LWOz5ENZal6-P^{*PNeHx<&~A9=+-!1#$|AHVj_f`it26Xg^=wqEXstY z57;G!+yuYIL-PA@@55a?^Om3*sVYaKc#w(FR;J|rxqK{vLZoeg1wtoinZqt0f*Sej zG{`~(Cdm}Acv7ek&L_AM_^-+YB@oBuPOE$rtD1_US9Wj%wsoE7R|#$cQSYY_U0iBv zIZ^`$^&NS=nhNqAey}x#=F#0v8hE2-1YS6b_3#3kc-|NHt^ufX!aCcEmQyLS514Xp z4Te-twB1_#kigP%b5mSVQeQAa!`boKwbg@~2+Q+*s02dT8(fUZ&KXsVg4iP>B2?@UmBMHzX5MS{ zSBI(7uive6$#@u25NHZ}jRXA|Ez=N12b=W8f|e9+TQ%LF`C~roF{25r$`C!dHTtE3 z>VqxC8#2n{!N1lvrpToUxTGY6i}v)e?$M|z&S%l2McuYNiU>i`2A@Nd41g4O8;X-X5XbA{D8qMxUa1jHonPK=i z=w5x2asdbKFQ5(rW}K}5J$@c4Sz5CGoNYFByeZkdsPX*Xr$Rb*_E-2S9gLdLo|-vl z6kY5TMmqes&cxWwnmY6N$7Hp>Y66w9rR2Y79|HtaZEbafMo(K?bafyptIoK}L@yeLUOXlF8)ml6Pj`nX|h{}JZJqrlv{S_BNgG>+B)i3(o1hmFH>ZiI0H(n9$ z-|XwtjPZ*br5L6F6qa9z-sTG%9n3w*-n_Be!sbNPcw2br@yYx};XU~)q*Qd$c0ez> z+2$m9xP95d&rbgSI*>A)q2?wSK0A~#hDIS4AK%o++jhk04JOwxj&%h1=%bA&oy|8Xfy-^2A(ebc+-U(s}h5KCCes z2J)M|hEE!Z>(BI~euL%PCOyFl7pHzcI-`IPY8Xt!;TZV#;Uu+%8%`rqoqRG8r-u!h z*IOpIxd{#FE53Bd*WQaNO@TXw@SIALXt(s0!@cE8eFOCJ$LZ5UuOwGo*`#+8r2e#p zpTwQmxViB?eE1OChQE80cH(PU-|8y1yeNMZn%+F@Z)eDm=E4z~XbrwvCYyN1p#G>aMve(pVE5 z52BqAJw5ayg#a2pSw&T~n}q7=cZd*LzBgUF?`pJRxfYCdTl)!r|6vdj5jTNRX$3Kd z0^KW5yyf}%8JX%b7dQuRP5dbN=sJ*}7_-P+*Lf*RhGY>pd*ukg<0uisv2AsLM;P%{bKK!p$ z$%kt;cP0Fx!1~5kIccfwN-il|y!CL+RroQA<|eS?pFSI&KV6eNI6v8;6>)m=JQ+l5 zY!#+!(ex<4u;OP66`MopCa7t&O3r5qY$vX^ZzbUge3@IU->Z5hak#wvEc*z>h1p@x zOq=5Qp@Y_)JFur>L_|b?+MU0?hmBZPnF#2Hf>IH6q%=hyGo0MYH@yk&YoS=3W5ZuG6}2je0}43c^_OY913API05fA z$h;{_bS6({^Vb{rx~~z?bX&4g>qJrk09TsTW_DC%XP zf<<0hHJhY&WjWUCT?^PFt|I~`CniES&cBJ@@K)LV3sA>5fta0NP~gEPfSlj6b$-^Y zkE$cNWEl2mk?qu^z737`Q@b%=Mgc`*`7X8kw+OKg<~FD)_?I)YYyiJ<*R}rSu&}Te z143YOdj-9T>5HVk*%*}e@Yd>Jwu&Wl+PKFtq8;@c8o8oJcF8eWuyKm*|3#S9>ChXq z-RexN+tUYXz;zRyb8>Rh(bJc^`0p1p8+&ydwbwcgvMPK&Kc0NgK$hPW@ROi*W{GzP zcBs_{ZA;2k|7R~01Gn=JB?yaWZ>(EG5Ki(m{L>UWZ`#`05N(;dRKRW$#9eu`VLt|W z{FNd;(DZaFDic7T|5CEU6tkkb9Kd-Lt4Z{?c%-Fsy)Eq|RGqh|6;BP)50<)la~0u8y0sQ-Z)uIyjp%y6J8iAC}mYin!8n8)XPnXuLt`OrB81cc$yDyy+fsfLS1a6F~2b6I3AF64npqI;r$~5>atKX;ZUv0#K zXvG;9gp@ND`W`3JO7^NYeT7;Yw1)U=U)c5w@#u_Osz-}voKa`W25uVw?PVR%{USrA zgKwj;c@FD~{$OL0xVW0L6c91hK-R6Bh`6Z(Sv%`|hf08$72*>`Q?b~RSW@bJF?1s6 z5yLW1m0B_b`Odlz!iiankS-NDKg&1p_O`Vv}5V~ANEKAmN{EnN2J zOucsaGhLG_aqj@DL*J_Df$-f=D_gj7Y?JS*mX@wA7Y{}4yLiytMok{VhVS1W1;~yb z&1qDjgXVC3JOTP1hME}46CZSxfBZ)F2{)gZ2aC8H3J~g#ydIpN?L;PLv72`SeTw@K zvD{+HVDUaeo{NiXRB}EHsr^`ImP(tp-l{o(?)vpR0HtKPrAMCbX)I!*#AtVw)r&#H z{674MWX{2_dE)Lo3JTUwxO1D>o^ZPXSMK^Do)WC#mrLPx3h1b}w7OX*_Kv4!V#=Wz#P-8;&`vC1tz;@jM!3#k8!>TL=URe| z@+5NKaROic#`$9{4J~cCHnjr4AA1o^L3{R#;=hl+7a8^9*t$=Ob!dcZm+q-|n&;s~ zs_{E*C$GXa=&Q~viz2jmd3jfMc5Zjet$5U5%b8k_=`gNVjwLxr zi#&~mCm>??WC{Pe#(}0E&45dlp|> zk_l$&T#1vZ6%Lhn3@~^DWl@iOkCd}*-Pa_Gf8 zQd4=Cn>DL zyd-FUi#r;OT?4!S*?e6~iMVle# zaSSxwkI}OE9B|QEmr+ExI;zvWH|4r2{VkJc0D)*v$+(MQv3Y}1*}O*T5E~@b_-4dbmsaup46}vPS=E zw=v055vUjfEJZaGOg7pj`t2{79K4=T?UJC-&c4h|+!s?|RKRhpLf&6`Wvh%|0J5)h zug!OLz+|KL;LNd>j9$8E4BZ>BS%MAZS^08|_#s!&IbrwxKT;`p1KlYqJlE zN=;y$fHKq&ok!1OP(c_5OV9 z$J@`g&0gCQB@lvHEK>&@O4~?eWMs_2DYq>fM;zAC444&V3P<^|!D62{;|HgQdoPBH zC*eWQt-1MNz!24Hv6-PE4ZUIk!NlH}l73}g&*#56ey7ia@LUq?mGW(m%0FCa?E4c7c;}=~ z4jzOzK5PB(8Ks8%Bxu#-!t9rqo^E^71XxU7Br=xx$`!VV*V;eUAK$i7kO}?sqTn$9 zn!0&m@He4B8v4h~X)SPqb--fhRV{68KTQ;>W&!pEmT}9N&~eqiJ55Z6+T^OW1@=D zsx@R{#~4tx=5ACW)0lf5QHf}t@}E!%7oNeOm5}PzaQhHII%OY ztYl$ZsgCNvFVjPXSkb^7y-}B%?i`Z}dreLpkKm&bR}N%6Zw8KML4_#Lv49=q%1tn? zaxULnY!e~wng0D7=sMUu=&PO{h#8D%))a$Z2OOfWSK9zC^xu{KYg14=mk|@RxM68ms|_e8>SM%q=o9GHviXF%wZM z%peO-&7nZ&%C^9trVD?X6xtDU)%b_xL57DbTe>&X=VHwt2Bj#niOrRm>qPZ1gH${K z{1x@?ljM)qH{|0a7J3l~M9dmsPDm75Djvi3O* z^gx)%h^k@q%3pz$rX28slO5X>6cj!$M(N&q@d{u%&J_{0B|G3rKp;U6@n^@sky1Bo z%lYosK07#zkK+MC4+ko-?1;w3=sD;D6&V@K&RN~EV3+Q-$Fzuy-x`HJiMo;-_?tC4 z1N-9tmvbN%g;Ek7zP=%8%Q8xf|0W9lWu5ARVw?Bn6qA=+Pz%X438-EcmYI8^xd9<4C{1fqaFbcxM z&Bq?NSmxf7CHB41>j3ccO|UEZ!-&=ulTynR!jE&-3NZb)_71Lpw`b{CSzoO9 zw#CB?=!w)&4}Yncm^>j+X1v@@Nul5~deZa=6#(g0o4sw^FrgKIAN9`J8@)) z%{w{dAqg+cTXP)Xd$LmIjzCjS$BfAe^;G5uCx1NatCse!M_a=BvhceyF??54I;SGk zK}4h@o+@!r7G$wF@jDuN8I*U`V_}T0dz8m-yT1))HTDPltJ)#Ez_*tQ!laQ4 z3dHxJ^sW>?#-Eo}^<<_=FuC~-h310N=_P%c=-Ey;lek}dZ%$x^CZJG%n#`f|&)zft$YpeVI`R~;P+ zHn|{!{k4Iy7C;=);A+k5TsZa18o4Uel%W1AeHn;Va1}ET$9DjQjm*vS41^sWz~kyl zQ2Jnv_ZR1(`|6$C^(_3_N0ZeyH*YipXq(5cyA+VaL{ubtZ`e_Jnw{l_$1Bc}*3iHV z?kiL$K!?eL9B$3j-*P|s^AkuB1jT;{J52*Rz5M*_#3)8r&a(`H=Mr%Ya>S|~l>fYVLxygg*|9@fBod~x>;KMovd;|UG} zOr^{TJQ~R?=8`_+|ISiDEE!r8Ga@2ouVmLTIXSuNJKkgm6lZ2;CTc$HSE{+O_q&uR zrS?npcQ+#=WBjeB#dElH#HrLGDfmXv#o1ri!`;QDp?zRlKdC4H#(J^1`xgViGZ6D! ziqD}XDjFFXc|pk{0cHK@RQueh(h$f5ex_w+kVgHgZMYFq*{6~*e0Iw&+-nsheCv-UziMCkhJ;0p23qZm$RALfp z`{~By?o!pPM$}~(q1UxjTU|{G+JBh@TUfu|ZO|IdsqrZY#6G`CL#zO7$d5qeEcnyJ z=9w=D1cqO}3-ImTSUJm)J|Y|R3<0LiS&@&;a*-U z%z%YRdHml21^2%(!TioYm>^8d4u>aRasrT02rH+i1B79wTVn)JnV*y7u5n5fDP+n& z{6D0CSU;%+%IzR*@QHx7evyLHf6A@?zbL^g^&d(|iQ`;=Hu?`GSJw(oE*)*EMSbdM7OgXp-URz# z5ulDdNzE_h|Ah;KGbpcY>}9iDza3Loa+na;Y9jeXz4n-5JKd1af9J^ z29%l_*%`Nj-?CM;l=v~x6_P~O;yyEH<5($a-(Hn~hpDiUYteGpBy~Hk4D=nF zYwdc4a=eJ7DKgZxx_7u1sJ9m8n@6{m?cA!=N9kU)76x2A~Ja8roAx^?3ox{7~bX!hZ;p?9H zq}1#>04`Jl=4MEj|iLGTw!9Kl@*BfJL(YHyrfg%UsR_nsqTOVvtf?N($XDOkFgey4s=v z_vucmgg1jnbua3w^JNUt*0J1^N;_Z65*FxSZ@&(-yDgs^C$>H(U}9@dKJu9VO&%1E zj*qoSh3C|O7fE<(iQy`V;eq8W2(R=j;1+d^#S!3Sm)v>GJqo-DatZFAL23W1`0t4F zeS?-mf(r0&lgi4<9wx~pM!&cha$OAfItj<2SeSMF00`_S9l#hQpZWirE?|uALzbq1 z)=aw{3FW+Y?Ha8jgWH#lJsxkOlqgy-hKumhE3u-xxA!aA_-i{=W%DpT41Qq`&Phtq zho#0PdniKKWFFYw(N7y)C3aL&qAgw9a#2xfk~@cIzwj+!3om5Oc5{{d0Pa{>SW literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /examplezigzig.svg b/Splay Tree/Images /examplezigzig.svg new file mode 100644 index 000000000..7bd4dcf6f --- /dev/null +++ b/Splay Tree/Images /examplezigzig.svg @@ -0,0 +1,2 @@ + +
4
4
3
3
9
9
2
2
7
7
20
20
2 - ZIG
2 - ZIG
1 - ZIG
1 - ZIG
9
9
7
7
20
20
4
4
2
2
3
3
9
9
7
7
20
20
4
4
2
2
3
3
\ No newline at end of file diff --git a/Splay Tree/Images /examplezigzig1.png b/Splay Tree/Images /examplezigzig1.png new file mode 100644 index 0000000000000000000000000000000000000000..11ec330f2a33a56b5cb2aa983f05d7b9ed7b97c1 GIT binary patch literal 13855 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 OF;o-~@>Q~yVgCoGitcv+ literal 0 HcmV?d00001 diff --git a/Splay Tree/Images /examplezigzig3.png b/Splay Tree/Images /examplezigzig3.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc40a3ba39fe01e44846dba5b16bd6cfed5a351 GIT binary patch literal 18128 zcmbWfWmr^g+dm4!2r~-85ITV5&`2pDAt?-@lpx(D-GX$AfFljk2&f<}Eg)Tj(n?E- zbV}#G#yj5UdH;LwV;}p2A6#>>X3dK8{MEU_Rh8w4E>m5`!NDO?ke7LggM*6#|Mp?{ zV2kL`$_E@AdK?8ADUGLw>*?@lt@iXz|JK*$QpKeBjJ(bS(FKXAvdX#Ilk~-Gu^4(t zkR%k|%|!x%KI3&krt#vFw=jp{JKbdGCzE#OM*Qq@!8F~BEOpVj(M^tIDc@Tcf+nq| zUyPJYR~HoWZ9i$;P&v4mIP;r2J8557TwJ_D29K7^gZmsW=eo=^;R?I_3`-MomR3#| zVP5P_kGubhTfxDh_~*icf{#yqJdcrKzQ%h-I2``4&fWgKUUf0Q&9HomfGvytcm+IO z>P9=8>bZ|FT!?XN>~ZGjcS@<|zkhu#v!4*Oo~-%6@AyOitVpXQWB9$goXv1vRtNzE z$`C{^l|--lxGy7tr}6Y*B%K8Jb7H#0vy+2@#&nS2bb;l!WarpP5I79nuVjqOf629M$+~!p0b;-p!%eTOF2 zbVW08-*?OK-JWYNbDEWYum7!h?`x3A_I4!cg8e-(4D@jbBnh zfRh@>uKuoT^n+Ofn`aCg+ECS;l4&Lu$GsDcK{AAghp!9~)|u3@u64}Daj~+>4Gs?K zZ#Jl5+%}!R_dSI;e%ebcBY2ye%ZYLxCB>|^h7ysDCg2m(uGJiqqdJ$8VxW^`ND04s z5uOV3&!pB7dDqBMa-&J%U}=+}n0vP|`Tks5^a<5R zPTa+KW4q2s>PWm%C2~|<+u>dKQ^}cd){N-u`QrXC45voycF8It)q1{*+x;ShD8c8wu zlKRd~|1vd9#f`GU_;9Fkp}5y>p1HYs(r7*7#Bh!rvGr(a7IThZJKL?+AR?kzoT|<1 zH?`?S-Pd?qwCxj^G2=8MZqYF)xy0Ia6}~dXgua-7dk~@i(fmi8fqhxLj?nL%tnc zQYU2`kFRBAW$~Pmd8{?!*8Q)gK6s3=q1EUZ>>3@RPA9YljL4!^r;#srNT#o2>g;$e z&7Nos+xthvOp7(`pzh-=hR-}xTbwxfuyJE@|M{KI*;i#AVoax~eTJK55iZv~zRHQU;S{VJ;g>7q!7z4uCdWtb@9*Z=`YDMhoKTeNsV(Kr5@ z+|pYuxobsLs0cNuv*tV0@;I|0v4rbO(FQqRozT+-{Eju7F(zjqxas*x0PNhE%f)KZFW+&gr+aaw--*2exJ&4 zCJal^HRbAp1r~#E6v$E3lZR~ZczGP>&F%Re)Oh~;r4KpyC%TrFEbU#x%9eGeDzEiF zy4YO*3SB(@kWJt(H~Of~?@XkfO|$=qwjAE1HPD}R&$E9(>drjQ&urNjZ0M__d{^M) zj5sQhTXR;X6~v8o)S@<9_zHMc({FVAm|)<^M9ZE^);wnMhLZGB$H=gu_iMJTN!em? ziUSCdypmq~YYNhW@Is?T!$dAUG+){0mr-$&G0>R_s^Uk%`_4r7cyC->9QFApf^*7g zr08T73Y|aRT^?Fk8!Lxww3(wX{rmN;0=^CHO(%gytF*9z3G2Z zclUIwH8wT1KpHPge2aDql&UK$Bk$E&tq0$P)4Nl1Z;KyHx~}-B^uuZCt#4nhy?*Ft z2GhvbP*Bbkr&+2x*D~^DKA7^z)IDNiVv_gsYq-19g&Hi-;(7n@ZA2{|zE%y4@o1#+ z{E-v)oQ2$g-vsj;f^?Om=EsO51Zv|SHXs>TKzSxnY=|O|;0`IljzRi_5e8g=AZ`uz^ z2;+utI9$OjhiUEi7@a?q{q=PA*>w$y5`(&TrXN3@?N98?1QX*M+Hd6`Fa01Y41h!3 zv?&8onvX#bDXTv}UJa^q;WakeV&u;i$Ewo6jxMEZ-m{H%=hg`2M3MR7+649BV=<*m7~wpJ^Q(&POd|J*SO*W$2|q zIqBTNDldAy1J`5d!HGbrSRiTtY#IWB)5O!C&d$Z9G!{`RqNt#tb|K8pt}ru6_(~&K z`R-$KH{z``Gy>KGw_D3M86ncU@R)k?>Y8s8*{H4?9;eA=+#gD=KjP|Bf2Gm5#!50k z>MJ*WRJXo2xVnE)fINfsXU6=NlJZCQj`6X=$rS=JXxE7ey}T;=Fv9Y$H6Xiz1{~Sa z#Qg+SzLsC4Aa6;H-J%~ND7*p&q}FbmT?LOB&iuQCh`fG0OsZujrE7EmGX%qC3y<>( zLs%4*&&4qrr{Zk*8#MSN2j1X{Ze`V7=uY^SF3j{}yc*|aRCK^2h?6EhowU<-x5h18 zec7=}+gG(Ja(r`E47hZ#85>x3cS|Lw`T+DAkKxTxg^5y=)~^ILx3C{a!R^K?6pk`F z+8@2khR?j7FVrc2qgU-fj=D-px)mqs;!>tdxwk$s(l-)Pw)Ut%6RwGNT64FZ>t>6e z`mDIBjFU;PP1BrAIkXO)@un_d^yz+x5fYK7$A=n=t^knWa@M^|48iu%BE9M#mYf{M ztqBM@IQ&os$0TsP+Ob5x4uAdecrMF0$2D3SgsKZbL$YY5EaX_r=jRGdw1Mx{a}_l; z6TxwH7^3kqH>T>UBUFR(s$`iXVgl29S(asS3UbcRP6|kR)s(`N%Y2SpDmgf~)iBv2 zBBL8gh^BObHn!kC)M0m|Zcx-JDB-ZVYKn!NRKc9Qm$0fks*o*ccvms#Rxp03dm%%U zk=paCH0D3MVs1U%njtmnOHeEHe!ltQX5jXGC#RV^8jUtb0(@|fvPfNB{l5L}_B;(4 zp8#k*s=vfYLTY#H?fq9?T6yo7o2&Og=QMARph&cl=PL^dCyoj5fRcQsU`RK)&nM8V z?f>gbGGiavK!CkXNx4B5<5sWeW}YqM*AxNuiAk2?=u$>$pDI0`X5D3`Voagx+-;^A zT-?ddl)Ii~m)VJOxW&h2PGBCD9GZno&D23$kPe&4_TVVSf=tWm?@6ZQb{E_02!^fW z)sh}Zzu(l%GG9~gG>+LIE1i4%KgTj>{n+nhU3@JSJj~_8*|Cycn{G-TLx-12c>`By zrE`TqdbbIWm^>d=b+)~nn2|x-9ULRnFJw2$`-H5qV*Mo6E6|jD61k9ylElfh@IRfW zOCb3MP{-)CdE=j92ow_^pBl-AFrmko(}*2-eq-a}P}bJg%(PY&gWt$eobiW*a3Oje zy1tWxO)Y7Sw~7?^nP<2s(u7^jJ1~^G)BBz4Cx0Wa7oTh`-#1s^mEkM9kLimGxCFWP z{A$8bt_mkZ?a4+R*U!U6RLwfETK8Wl&uZZ{QD$oS-p)od{U;CkzXI(YwUZ#w-dzJLm#*a z-(4G1KQs2fIGOhDfY#abk~&T|7|;*|a9+KUwkyg|OsSt~oZ4X48QERqSI}ouGOfb5 zlfu^Xf+?^-tK@PB%*4a*WMcZb1;-?MD>;PXy0VkU<`08f_x1dG1uti1_+rS+Grrrm z)dd|U*|xX0V`F2p#mTO;z>fxbi!rBd-DNp4GoTAYu9pjSE$w1n8W@iHwnkY0jrpaR z^wNx4roHx7-cQv~3D~f;dLHd8B$P@vxwyJ602t`9zoygdFbZzq1%RHr`y>BB{CO0r z3LD~U-$%NC>r?7vwLO-9jfAkOWN2_^chdQvTAB~j8#il_5>CrS-iRS%Rqg^$oDe^eakF%Q!J3j9U{d z+axQLP-6J0c5$J+sRhc0zCpp{L=br0@Trs&I|XOU_xK`| zjmqE3k_5aUf+2ixXNxJ-oxt}se^^Y#W5IcTM3ViS&QIIWckf$(ZR?0SMhKr#Vdi(A zgqCzjouw0A3;A8#2(>NWCaSh19Q{J+FhiehSWOt|6rO7WphEQ@dvqoI8K{>7`wNeTkvGZP~RnkR!%D zRX6wRYbvYyy9Y5J%sM&LOkLyxOn*kwxq8dv)S02snCP}PnLTUGTxA;K`vdh zw(#?(ysmCah27X-=5^WE8WCzx5n)0lpVgx3cri9HF@p^M^CMo3qbd==f>Uo{i{opT zt(oSmg2t;9?~u#=R}dw5r%GnkcA(%6f+wVZaJ2k!6d@JAJopdG`}gm&?B!G`a*>y0 zGd3SVkM~w{vGlH3`-ADyd!OH5?{tqw(o_Rl9MT~6!49XLEwSRLcmg()p$$r{#q!|W zju=WIr`P%b^~qj0DMJUCn!hB=+)2U-$pbV6qW9uGysG5(<6hP1o9?{rU5sqvzi4oM zQWCiIzIRa!q{o*^*E-MRON`wlq>G5TB=6HE3gOkH6Z6uzb?a6=r^fGCuiYgEKpWqv z)y4Z|Bdx`wmGWu-u)Eicl_|!BRpWPfZ9JCxrO=T#KHFcAzE;B&MzV=7M&MlKud?~3 zIOEFpW#T}Y!FZxkDOIq{W7Cipa}%Gjy=!^NR9p`V+CLA_ABYzM(RxH&vnI&ZS3E}C zq8=N&`SLm4SxCxn>0W~Pf9Rb#=!#yNyrGpVp#Sq*^#^#2MHnmdMa)WK<_i9U092LHZJ$X$3$qdqd zt}PsU-C&jDy6UNd_8jGwU$cX&^qj!&c}XL_5P-!&wc#akX8Z(Sx0tVN%*}>g0EXei zE`fRW5YsYh%aC{5Vb<&sAgm1}!-7d1f6+Xrp3HEE$HMqNj5vA-9~pw>^6}hvo|-o` z(TDL17UTZ(3*BAiS?xiWVf1OLb?)mwTb^ABd3ZU{=3D;fVuQLjKthRmEXx;hO0q@U zRAD_7AC-Odd(qpd#)LVNNBN0T3qysih}yew`7PNqa5i4=Ef2}1*I1UJaahZ=N(^a^L~Y4Yw)4+abeMQue?1WP zKffz6aC4`{>`ziHnhlSgs`tMWkSTKVk62l=yDt-41rR{4WEfbbBOyaK5)X(gSEXqpv`SDS53)f#b7TED3zF z>--7mPYNn3*O4!b{EjRZwv=+AbYo%Vp^a)v%h9O*%F-TE;|BzYO_qf7+;#fs&FWwDw zcVB77=2xmVHu*CZPl2X)?Xc9e;88&$;KZ^oj-hJs2sM&nB45_*wz)zKx5O6Y3rWu7 zOkYh}&!31r|4)D%VU?|;q0Dn8i|+V=>^nO%+zXeDNnvJjBcJVOJJLtZ1aw`&#Nv5G-W%_LUPOsu(U2K& zMPHmWUT|))M5m`0@wR@2_fjpFaY&~>?F}I=)2`XIq_huXmKk5F5Hzj@b1YW0T%VFTo|pb#+Wy6z#8@G6Cn9G~&z0x3iJL zbYfq0m~a8@lHgrh-lqHVbZOvx)FhG=28h?$tP~yCkn9HWd>^Zlxa*;|-9s&jOc681q!$X+@AUX!< z3GDWCdU_%Tj5Pu1s4<{!X<5p(G9mW0oz2k)$d<(4Pjaz^eLYeG)h03`1#Yk^47{k zwPW52&5Q1qTvAQ6UX@*V`>OQz)d)4VTK2SrHddIX904&c;bT0X!Y4!Tl)mM|GRq!Z z&`a{o$!{g#*vX}fdL$0y$ekQ#@KT67{?gD+! zeS0{l2_6**s((EABSlaVgYtr^Hs2tvCj@?J*sTn|k4;Em2C^+*uG&?-!8#Ae=J3_! zpLl?vUr-cSG z-%rfD7Yz_>3<2%arY;InO&K7tz9AVy3IbiM^f1pG@_VuG6;MPB&bOXRge%KV$dq?!mlw?0u_FpuNZJ^(smNd!;TjW&VcRWiFFkF`-X$`R0s z>DI_m{x#?_ji)?qxnrCq^^6iHV|_j*0le~u4|MC?i?C+Q!N$~E(DJ%d-&|jecT$F} zcYXO14`{t2sOWFryvgg62_@Tkd*AVzBHzv{M{~uCtyba$l4c`fO|B2}|IN`R001p$ z1oEkRowI<=a5TrGd^VIw$R$W(YAR=`b-I|hW+}D%>7lc*&td7>bfeMP`tbWWx8*_E zqJX6h)HSiAC=b99I>$%v%#z_}@{HCJ?~vgiOl~DV{n>>OcAg7K6M3T8n=YFBA9m0G za*!yqXI;bCkr476;~MJUnrTJJ!mjT~8D(ND7;$p}qfq|LmpRVfdc**jz{@20CL-L3 z7-}y>?~C+Xqt-wCFMQtv2`EINblDIAu9)mC=>5e)B$ zh;E*|&&_yPAd)lkGrn0+VZufP8dt>Ta=P8rwP230sf!qhE`}+9X z5G$ZYclVKy!4DMxq$isy&BX5zxB^3P=gygOfUQbkE5amhLt!@2>*D|Z~$boR`*>s&LzCs=9HiE;|dKS zp{27dz}R@1pA88H&iT;Bu@_m z=lfw^D(!p7;`5nR0%`K=*RQuBe~Kzdg0o0*o8&>%?B0~e^!p-jsD=!a77HmX1*bhP zjFwldmL0+&9fqxwpq>zW5$>EZH6^I2nKkX!Yzjrfjcm0e$|ZIiF^gy$mt$c#==MgZFO%NAPt)=RsVPJ-Fi2^H1l( zS>FJ}S?0FtTEih!vB82(M{raD=+p>g#Z zkN?q&_e$n<(#rHZrXecj0B=!!WUO_yGkxYZ-$AtZxkCn0iwLVgHfz6Z^`oSutlfLz zxVJoz^PJyqG+KGk2lXW=oiwZvX>#J%9CWG7tn(@g^G%Zg=U>OD8#pgTmh-MmGopd= z5s0h&a~L9@tCbE@;~rhLpK$7IN*UIt>R!#JK3PqJjj+a=4mbFEFO(24BfhSQCVYnE=l3E#3*hOQOG5%l z!@hLGA_rKM)7Y>bn7k&E$8o&k{g)Jh`&e6&rl3+%$b!yun9m^Bph0y*#b5pYT%YD4KRbSMzwb8#=~hI*2UF<3i~)6tfc`p{?i(Lkz8J|u7?Kmc^%KSu$$~!F z@^&(oBl4+Fe;xp4|i*lat_|R!j`gFZ=`FTOJ$wslo;O8Cm~i z0gi;=LafGx$l1$X0l0W?fHmB^EW^JDn7GAQnMFMn>A*R0{#Zu@!bh*QGQU^6*xC62 zVDmUFLr+=I`N)QmY`cbsU7`04Pc0Y&wGq6U7*aB_gs<{iQIT53`Uqr1D!(xjeP80gxr6#jIaV`f1YiB=FLS79p~?@~L6`YnE)|1I{wVXFND-#=lTm>tSD^8& zzkhKU>5KAPB1J-%MV_}%aprEKjX0CVxU}LP<(Xs z>lW5WMY`V}J@!gS7DScEm)#J>9>$c%P`^TF6x}PsPhQrKZ_hcTq-T<3?qM%4d8jMe zDg0#8weNl24H3#x&)%+r%eClF9rvB45gKu zDKBDo{bSriob9RY^gj!-B~V}i-~|6HpwG&cJHZPEjtp>G9I^M~ZlJw?^j}`gED>%_ zdl+zGh)K}|AAnm^&tP1ES+RbF?TB)_iWx^T&fHt@P~Kk|DN)g2B5}oj8a9V@ zW3E!(V)_-(y3^AB;`$Z$!I>wq;m{y@5;z|y<#7+vgko@M?jucvmV|7--&_VYhGaf^ zlL-fI}gYVYx|-wY%HVnR?q+2`-q}0~ zQPKJP!@MT<;g7D5DaE|pRO>6fH|srrn}Z8nL18^|d!Rt|P1_PE{oMot`t>VRDqM;8 zNN8!O1?|{?91{=3r1qU}KG%UcOTx}4y_&0>&Y`2DQwFwo5kLR&$@_}3KIqHt48p=lA}Vnz+)V3u}V)#q595J`U4cq3S^eb$=)h!n0OuNZujaAGrtBo+R9WK zd@y~sZEu0sDu?Y{+^tiUAX{@8Q~Qnux!RW|-1=MQoqH+ndN$H`I-G)5u* zPx=xdgQ2fNNMX}9n8JexgB{a$=kIxyJTLIAkC}e#&(%NG+<(8W=G7edtagH zmaAX_;_d*KQ-7$6;93n4o%mhV%<)nJF8vzS_4wH#Oyq!_8x!5PSOATrs*V2v*<_P{ zfouZiv7VqBODEqT`{PI&QI2^LU(E@#uG~E!8M_SJfdz;3y#YpnqM>01RvrQ6gJX+j zxm}n!jV$PT$Cob;#(>KU>g0Vz#fakv=0XhDX*vsaNde9r=K4=0P4T(P^Y^b6$4_2+ z!w&i{sRZ6ACU9W+$>+YlS2Z<4pTB-h0CB3%fMQ&#Gr^V}z#MvjL-=hPq^%TQaT^R@ z4%-mFyK?hd4l{skDpL?61zsOIVHX+YG$96XZ^ybW_Oj0&?N2x+AQRZt(Ht6iub~_a z3{o~D#ay5^C!k+avESqOxe6MQ23Fr69pV*g-09|AalPs>>$g{61ZQ+T-SB8s&ol;Q z!2-ZP`*nyKv=-1I%|)3Fhkdj9{n^EYA2Fvv9|ZAngSY>Lxh2SqxS_or@MwG zv|rI-yr=#b0)X0P*y&0^iI<;?$Pz=)(9D%IJqpni>X_IGnJ^C znD;)vgSpS?c4v1Duvt`k08)8rOGj6>^0mb?sv&ARQH!sdriejk*?UvpN{bI)LgCm*IYP?{lxLCv9=zQmuVswV*FUmjX z;wicb#ut&|JZ`^<>SEGV2=hBhoj&cbcmARR$smDMB4ww9)-9p>b?!=IF(l2`3f}mi zRQtQC-}oIHU<=8jKvCry9DL%S2Pq8T@a90RXPN?kkas_nZ^8}i4@ZEz#_MDJO(48n zfM1HW21qk39K!o=?fh3|KZ%O(M zF;;1j>&OmfJ^k8ewxleiVa$O|?Mp){5(#(&SGzy}4eFPn@>k$eeFO=-(Mz}8_4U&L z_z>&9aFv!08ZI`_GjOyT&Wqu<{r&(nW3u~}pzB2k5JOG5(V4#c$=I}n69-c73(x=( z{}6iEI^oE5z~@z4)c>kMTBcBwAW1BppIIQOll(Vi8P*V?Dn3>FWS%v&HPF<;G%PAg z>#QZbnZewWGg0zE+Y$&Fmf3vc&;ine?lQJSraS)|vpm4ML1j-?H7Tx9ZLeq@|*iDj~OSeu}wu{fY(Qk z!PzuSnkRJt-PZWS2_iCA=#Q;ND54)m@H^I3^Pbv~HFYObM>QgZ)9 zD{m4;&U~PLu2PkjcH;?6O9h@^8uHMa7=^248uHYj^#2G}lKf&_3n#lb>dia8=W!D~ z-x;N~_$=|J4kO5(T;*y94_X&C@Zg|lV`F1A(HzcDVbB@juhJBQG)biuwcx$%?X1kU z^rK0b89DJ`K6D<(%%Vt4Q}zBDaCf4Yiv7ny1^@cB7>X{Py#0 zBq_zFviBK`?_=m?1Z=-+5Kt;9mHN(RTOpz0WWn!qcvIHPZlaR{0n@Yn8L`w`+4u z`w8f+7+y`ibpvFjsM``fN-lEPW+Ia;_#5p{R}++KHga}Su|Ts3TFl&1@4H!{Ub;?f zqyS>O-{y>&Sn)rx;OEXq97V8zh0UxkKoGg-`Ffz>>hlkNATvISxAcHFf1C^R3R;cBC!&ISy?RL&oM)g*mi352WR;E?T=4m$?k1$1tlT%-I&XD>77!Mv)9D`5bN@2ft09L;f{WV)}*4 zOK!8_JhkovMAA`=5TAA~)r;_EFZ;tc)Q~&vFoeNu4%;>7uag?u&+Ef_LQ~Je%va^+ z+Kkilr^$l%QnnPTp+KR?m-=5}&4x*x`8MMs;;s1qSoSqdSiLt>qECgNnx78^&2L87R6JtcD*Y?J`7Um){nu=pF zSz$|!aiFD{eT3LYPD&gPMESk(+r8MPyT~H!sAUp5mZouaak=}Rlm$w|ihtSm;_v9W$}8aDW3K!#h>ZyzBWee4z2Pr%~R^t5&yYP6Wd}-vN#_ z?y3bt6|4=!Mi=J`3H=U5-h!%;Cn5$SmHE1$w8vv}5?S}2YnbcNJOudMn3Hzk@h5o_ z9U9h9y$Scdl}CYQb5f8;G3@Ee6wmuJjFq2b|mnRXTZq*@8 zj~$V~;d%CzSou)HZz=2fPmsD^G0bpK@bIhM9xM_cAII=+0k`YD<~?Aq4lB*SSH}5t z&fo8A@n$t2X4bMAE|u$iEuq$`E;ST+Fg7-}(?RVx>3(tLPQ?}XCqWxbB`@EJOkjZR zmS@^&|D#?fh2NT#|5$qSz{|A1I1rH+ow$fG4yNR{iatF*XlyLHvh^{vDHe#`-?DA% ze<*){a)+qYc{tms(QilM;)veWAz~ zn=+*|R3YrOZAnvxgH)-y3*$;&;Hz^CkT^UaKNaH>DuKI-FiWaLUHyDC+yCMmbHhE9 z_@7ib?$yonbWVjHGD; ziv_@9xN8kVQ&`#6r6WqAXy>7||5$vdJ&Ylt$ZS{i%`H^7?&cK*hR`@K~|^zS-}2 z5h&q1ATVqdy-Y(E=InW!mKu_YFDEwHn?f_CK-SD$vXeA#?oT2${))Z?8K|wx9j2fN zU-N0YS#J>NeqF(7NYfuj z2yYXhd0y3~+1s2pl68G)BORgz;k~ zo?b?!AFLH8yVq~lJbdtq18pUg{jmk>o|*Bz0eyk5LC~mXePH*R8)u;n&n3uLW!u~In1q=`fj?tZp!-_-pnrc zYv@@3C!aLR>D=NkhcvH6?D;G=bul@1xX8uDg^7!cYYXqCAtAmpA$Af-iqweWpcVXlc`ntF>c!&8$l|J(3vY=O7e=jt~^lLg-o__84y zm=rcpR1^?HA%Ou2;~wB5Kyk06-f=8G|6ZV_vflA6PwgIdm~Elwl~xM`x99(ZJi}(? zLDz7Q^5QyZwzyF`zRV=9e6{5QTM5vU4nX6u-N9vLm|fUoBaM_6MiP?uAo=Vx(TWkRf&>koxo&lybF2RZ95;O!J@s$tu;qIcTG)FoU_GCa+E?GG;C8&h;% zFuneS%=$hW`^V2UfE6&YkkaG+hJ{FD0%&sU8_$nzbv}7jdVXrU7J~yPr@5n~#T_Ma zUK25h=(ti;d&}aJyySIAmJTKEX!W#Tf%{jdp7TYCi;vudI>cZ{#IO)WOuyk;tyHuV zANjdYl6(O43q6SlA7md0J~Cj8}{J2go(rtl0}X(_CHy#{≻M%oM94;*+% zs-#srY}8qlCdTmMuu~$m?z*-&DSe>R`a6nmM!c4&<})trz~NJPh?j*%z!^v}X$~0W zDy3fgkzxE*fqo8(Awf-A1QXyKa(ZoiTx9(5)=nHA5*L6lh3*2b@F=Ll@679{@8Y!2 zX&>KK34&lT#vrqZ5k80k#nRSL>azz-l8{*j<9HAstR`f8zinjK(If5cyB&(9>D(YU9A0bcDCuSkc|IF4C3{LKCz`sXA8I_x?_@t*9ACN-f4z`G@uyClnqzYDC zFCB`i$_S3CWDL}U%SdDTjSmNUySh|4nT`j3MS*WZkx=qMyp9LHJK~g~nN%g|ADV`s zhoS@tB!Kb;3J-_L1T^Z3faX2yVo{!KVij<7&tayPRHN%~tPTJ+oT9tD$pe z2xMk9mP`%@Xo2`$+lrPLe@EUASf9m6+58!-O<5;Cq1AiH4UNYPjzf~-*OEQ z8WpdD4KDkMs=ZG}SR3^3snk4Pg+7UkdR;#3tx3)TJR;xS0lA%V+mg?qs#zRv&E7Ka zif-z_saNC%VmSv8OMs;sCr9VYUs}7>&h#3Ei)x33E@5X`K=mJw?R*@|4bKdRrN+m{ zzqt!-+WHC}b$Zh@q*MqP3PIhr{1Oc~kL^S!7KHpg2C-ZvGht}jZmQ6PqmW5

~t9TomnK zsmVR6O4QK&fW4Jf8*JhLtEUbaDFG#f#^pak$o>WWhx%-AP^g_=e*pL$l6lYMM}vom z^dA`n_Ex5vNtyjt<_1)n0UfqG-spd!N^7-igVUtl2quTdKDy>=$(G$9?T-l9HwEE& z;Bs|S$PJU}XZ{sB&K4&jv~T=w8ZvR9P0?&c6Iy5K7li0=Cy^DxMWDYR|^P ztT@r1KYw0fX;6+FaHCYLdGVb39B`k3w~B=X@EVraZ~qlDT&E<}uUP#_2@K>`y%)Rj z$=w=^-~ByL`h@PXHs!2(Viju2J7TX~QBssoS||%-WMn#F8$DGRP zV(fqvz6PxzMNLYr4&_FPIDa*NiKA=|rXo^2z8B8UsZ){lD`G5r)7TgLG8b7>Ug8F; zRDuf9^F|@g?&n+%(`!21qQ5i<(~3u{c$fYS6}Pb}NZy0!hN}U~VwhVu{*>Y)4cY%> ziX)B`=v5)(VF(`zA{vo+0vZ}Zf*S$)6;?4jo}h1q?yr7vtY2hs>U4K~M- zZ&WA;;=2_JZPtNNLr9PW#RVzh;NbgX-wUvj{FxRv z53m{%0t8Ltlali6(6yd!*r7%d8=UHD5buqNk0Y0G z_Cbh~jE>H+4&i4h`NccUyM_4t1y6%&?~iv6lCzpdHw*?Y2J`c4e-B;0#tFXE8-@v`k01P z3oWt>S)EA)-}@%#>k`0{9I@-7oAs`@`AP0xrZ2Bjv^JtaFOr zN3ccEtxxPAuP0ACaK`-TVt0B8jQ1p>upvQS3|FX{YDjzc(W>62B&_f9zY z$}o@}aGRFc*>Xq$vzzaUv74&*(}^#GAVF`W@E!xWZ3g~lnlo1%ySx9&5QxF8nEx|F zki`ma;Q!1J>@vMh_^%8>2KM>*uMEL4S-H?#5tyaXYOU`-2erUNQ!jb+lS6yR+MrizmH|0_pu`G0Z* z4+sd2&=5aF|3ggw=$|}sP^#9u2{<-KApCTq%;L&GbO0Z;f&%3eWcF z5Ha(yj5%4pi5%1~wZL_lAqA+(_Lm(;)|2iyX6!U8>BZQ_-;}%!(S0!xh)3|o_hi4j zy}$v4h?nG^x&fIy3k0!#zoVX{UupJ;4WNToTto3c1tDTc;}9$xxd**oBjhXwGDdkh z#wSEr^c^UyDF<>YS`2A9DI~|b&zzj z_#ck@CnCH}K+O)!FhFhv55cTTQ3M5NXv4fQptpAq+2(R}mg?e&N)_mbO*M>%JGd@D z(m2HHze2#m5l1x$s5B3H>5|>ae5k*dmlqo`x@BMB&uAtH{-RHdM_~k5fL}pPfco1@ z;h1zqZj{Xy1CMw#t*%WJMMBno}WAgIpn?|~^R-wC?v&D;mcj9{K| z!Qi&5pNd`h6-Y-oLVKo4LWW&bRFCCB((8m^LFB~WuhLKq0r81n*(XT}&@WhwPvJ)V z{}S4D^^>s+#|CS1ATp!&!7)!k-fabXN8h=^e&RcI5Oe(hP7$0$rt`qq1Leciq^9W! zNyX!U;Kb?a={fkx+hcjWvY_dobgm)t_U+pi0D6(q(eVJRw{kmXHbnaPib Date: Sun, 21 May 2017 22:20:42 +0200 Subject: [PATCH 026/528] delete blank images space --- Splay Tree/{Images => Images}/example1-1.png | Bin Splay Tree/{Images => Images}/example1-2.png | Bin Splay Tree/{Images => Images}/example1-3.png | Bin Splay Tree/{Images => Images}/examplezig.svg | 0 Splay Tree/{Images => Images}/examplezig1.png | Bin Splay Tree/{Images => Images}/examplezig2.png | Bin Splay Tree/{Images => Images}/examplezigzig.svg | 0 Splay Tree/{Images => Images}/examplezigzig1.png | Bin Splay Tree/{Images => Images}/examplezigzig2.png | Bin Splay Tree/{Images => Images}/examplezigzig3.png | Bin Splay Tree/{Images => Images}/zig.png | Bin Splay Tree/{Images => Images}/zigzag1.png | Bin Splay Tree/{Images => Images}/zigzag2.png | Bin Splay Tree/{Images => Images}/zigzig1.png | Bin Splay Tree/{Images => Images}/zigzig2.png | Bin 15 files changed, 0 insertions(+), 0 deletions(-) rename Splay Tree/{Images => Images}/example1-1.png (100%) rename Splay Tree/{Images => Images}/example1-2.png (100%) rename Splay Tree/{Images => Images}/example1-3.png (100%) rename Splay Tree/{Images => Images}/examplezig.svg (100%) rename Splay Tree/{Images => Images}/examplezig1.png (100%) rename Splay Tree/{Images => Images}/examplezig2.png (100%) rename Splay Tree/{Images => Images}/examplezigzig.svg (100%) rename Splay Tree/{Images => Images}/examplezigzig1.png (100%) rename Splay Tree/{Images => Images}/examplezigzig2.png (100%) rename Splay Tree/{Images => Images}/examplezigzig3.png (100%) rename Splay Tree/{Images => Images}/zig.png (100%) rename Splay Tree/{Images => Images}/zigzag1.png (100%) rename Splay Tree/{Images => Images}/zigzag2.png (100%) rename Splay Tree/{Images => Images}/zigzig1.png (100%) rename Splay Tree/{Images => Images}/zigzig2.png (100%) diff --git a/Splay Tree/Images /example1-1.png b/Splay Tree/Images/example1-1.png similarity index 100% rename from Splay Tree/Images /example1-1.png rename to Splay Tree/Images/example1-1.png diff --git a/Splay Tree/Images /example1-2.png b/Splay Tree/Images/example1-2.png similarity index 100% rename from Splay Tree/Images /example1-2.png rename to Splay Tree/Images/example1-2.png diff --git a/Splay Tree/Images /example1-3.png b/Splay Tree/Images/example1-3.png similarity index 100% rename from Splay Tree/Images /example1-3.png rename to Splay Tree/Images/example1-3.png diff --git a/Splay Tree/Images /examplezig.svg b/Splay Tree/Images/examplezig.svg similarity index 100% rename from Splay Tree/Images /examplezig.svg rename to Splay Tree/Images/examplezig.svg diff --git a/Splay Tree/Images /examplezig1.png b/Splay Tree/Images/examplezig1.png similarity index 100% rename from Splay Tree/Images /examplezig1.png rename to Splay Tree/Images/examplezig1.png diff --git a/Splay Tree/Images /examplezig2.png b/Splay Tree/Images/examplezig2.png similarity index 100% rename from Splay Tree/Images /examplezig2.png rename to Splay Tree/Images/examplezig2.png diff --git a/Splay Tree/Images /examplezigzig.svg b/Splay Tree/Images/examplezigzig.svg similarity index 100% rename from Splay Tree/Images /examplezigzig.svg rename to Splay Tree/Images/examplezigzig.svg diff --git a/Splay Tree/Images /examplezigzig1.png b/Splay Tree/Images/examplezigzig1.png similarity index 100% rename from Splay Tree/Images /examplezigzig1.png rename to Splay Tree/Images/examplezigzig1.png diff --git a/Splay Tree/Images /examplezigzig2.png b/Splay Tree/Images/examplezigzig2.png similarity index 100% rename from Splay Tree/Images /examplezigzig2.png rename to Splay Tree/Images/examplezigzig2.png diff --git a/Splay Tree/Images /examplezigzig3.png b/Splay Tree/Images/examplezigzig3.png similarity index 100% rename from Splay Tree/Images /examplezigzig3.png rename to Splay Tree/Images/examplezigzig3.png diff --git a/Splay Tree/Images /zig.png b/Splay Tree/Images/zig.png similarity index 100% rename from Splay Tree/Images /zig.png rename to Splay Tree/Images/zig.png diff --git a/Splay Tree/Images /zigzag1.png b/Splay Tree/Images/zigzag1.png similarity index 100% rename from Splay Tree/Images /zigzag1.png rename to Splay Tree/Images/zigzag1.png diff --git a/Splay Tree/Images /zigzag2.png b/Splay Tree/Images/zigzag2.png similarity index 100% rename from Splay Tree/Images /zigzag2.png rename to Splay Tree/Images/zigzag2.png diff --git a/Splay Tree/Images /zigzig1.png b/Splay Tree/Images/zigzig1.png similarity index 100% rename from Splay Tree/Images /zigzig1.png rename to Splay Tree/Images/zigzig1.png diff --git a/Splay Tree/Images /zigzig2.png b/Splay Tree/Images/zigzig2.png similarity index 100% rename from Splay Tree/Images /zigzig2.png rename to Splay Tree/Images/zigzig2.png From 5d15f553817310785fc0d5539c01508c86892250 Mon Sep 17 00:00:00 2001 From: Barbara Martina Rodeker Date: Sun, 21 May 2017 22:27:24 +0200 Subject: [PATCH 027/528] Adding images for examples and rotation cases --- Splay Tree/readme.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/Splay Tree/readme.md b/Splay Tree/readme.md index aa6bdd4db..89444b2cc 100644 --- a/Splay Tree/readme.md +++ b/Splay Tree/readme.md @@ -8,14 +8,25 @@ Splay tree is a data structure, structurally identitical to a Balanced Binary Se Given a node *a* if *a* is not the root, and *a* has a child *b*, and both *a* and *b* are left children or right children, a **Zig-Zig** is performed. +![ZigZigCase1](Images/zigzig1.png) + +![ZigZigCase2](Images/zigzig2.png) + ### Zig-Zag Given a node *a* if *a* is not the root, and *a* has a child *b*, and *b* is the left child of *a* being the right child (or the opporsite), a **Zig-Zag** is performed. +![ZigZagCase1](Images/zigzag1.png) + +![ZigZagCase2](Images/zigzag2.png) + ### Zig A **Zig** is performed when the node *a* to be rotated has the root as parent. +![ZigCase](Images/zig.png) + + ## Splaying ## Operations @@ -30,9 +41,20 @@ A **Zig** is performed when the node *a* to be rotated has the root as parent. ### Example 1 +![ZigEx1](Images/examplezigzig1.png) + +![ZigEx2](Images/examplezigzig2.png) + +![ZigEx3](Images/examplezigzig3.png) + + ### Example 2 -### Example 3 +![ZigEx21](Images/example1-1.png) + +![ZigEx22](Images/example1-2.png) + +![ZigEx23](Images/example1-3.png) ## Advantages @@ -57,4 +79,4 @@ With *n* being the number of items in the tree. [Splay Tree on Wikipedia](https://en.wikipedia.org/wiki/Splay_tree) [Splay Tree by University of California in Berkeley - CS 61B Lecture 34](https://www.youtube.com/watch?v=G5QIXywcJlY) -*Written for Swift Algorithm Club by Mike Taghavi and Matthijs Hollemans* +*Written for Swift Algorithm Club by Barbara Martina Rodeker* From c4268801a9340b1776c6b4e0c452fe8a6388031b Mon Sep 17 00:00:00 2001 From: Barbara Martina Rodeker Date: Tue, 23 May 2017 22:08:14 +0200 Subject: [PATCH 028/528] Update readme.md --- Splay Tree/readme.md | 64 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/Splay Tree/readme.md b/Splay Tree/readme.md index 89444b2cc..29f9dede5 100644 --- a/Splay Tree/readme.md +++ b/Splay Tree/readme.md @@ -4,22 +4,36 @@ Splay tree is a data structure, structurally identitical to a Balanced Binary Se ## Rotations +There are 3 types of rotations that can form an **Splaying**: + +- ZigZig +- ZigZag +- Zig + ### Zig-Zig Given a node *a* if *a* is not the root, and *a* has a child *b*, and both *a* and *b* are left children or right children, a **Zig-Zig** is performed. +### Case both nodes right children ![ZigZigCase1](Images/zigzig1.png) +### Case both nodes left children ![ZigZigCase2](Images/zigzig2.png) +**IMPORTANT** is to note that a *ZigZig* performs first the rotation of the middle node with its parent (call it the grandparent) and later the rotation of the remaining node (grandchild). Doing that helps to keep the trees balanced even if it was first created by inserted a sequence of increasing values (see below worst case scenario). + ### Zig-Zag Given a node *a* if *a* is not the root, and *a* has a child *b*, and *b* is the left child of *a* being the right child (or the opporsite), a **Zig-Zag** is performed. +### Case right - left ![ZigZagCase1](Images/zigzag1.png) +### Case left - right ![ZigZagCase2](Images/zigzag2.png) +**IMPORTANT** A *ZigZag* performs first the rotation of the grandchild node and later the same node with its new parent again. + ### Zig A **Zig** is performed when the node *a* to be rotated has the root as parent. @@ -29,7 +43,53 @@ A **Zig** is performed when the node *a* to be rotated has the root as parent. ## Splaying -## Operations +A splaying consists in making so many rotations as needed until the node affected by the operation is at the top and becomes the root of the tree. + +``` +while (node.parent != nil) { + operation(forNode: node).apply(onNode: node) +} +``` + +Where operation returns the required rotation to be applied. + +``` + public static func operation(forNode node: Node) -> SplayOperation { + + if let parent = node.parent, let _ = parent.parent { + if (node.isLeftChild && parent.isRightChild) || (node.isRightChild && parent.isLeftChild) { + return .zigZag + } + return .zigZig + } + return .zig + } +``` + +During the applying phase, the algorithms determines which nodes are involved depending on the rotation to be applied and proceeding to re-arrange the node with its parent. + +``` + public func apply(onNode node: Node) { + switch self { + case .zigZag: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node, parent: node.parent!) + rotate(child: node, parent: node.parent!) + + case .zigZig: + assert(node.parent != nil && node.parent!.parent != nil, "Should be at least 2 nodes up in the tree") + rotate(child: node.parent!, parent: node.parent!.parent!) + rotate(child: node, parent: node.parent!) + + case .zig: + assert(node.parent != nil && node.parent!.parent == nil, "There should be a parent which is the root") + rotate(child: node, parent: node.parent!) + } + } +``` + + +## Operations on an Splay Tree ### Insertion @@ -73,6 +133,8 @@ Splay tree are not perfectly balanced always, so in case of accessing all the el With *n* being the number of items in the tree. +# An example of the Worst Case Performance + ## See also From fbd5d6ea149cccd61c93530a772bad148e3a45e1 Mon Sep 17 00:00:00 2001 From: barbara Date: Thu, 25 May 2017 14:04:49 +0200 Subject: [PATCH 029/528] Examples for documentation --- .../Images/SplayTreesWorstCaseExamples.svg | 2 ++ Splay Tree/Images/example-zigzig-1.png | Bin 0 -> 32202 bytes Splay Tree/Images/example-zigzig-2.png | Bin 0 -> 34485 bytes Splay Tree/Images/example-zigzig-3.png | Bin 0 -> 29732 bytes Splay Tree/Images/example-zigzig-4.png | Bin 0 -> 28709 bytes Splay Tree/Images/example-zigzig-5.png | Bin 0 -> 25735 bytes Splay Tree/Images/worst-case-1.png | Bin 0 -> 6795 bytes Splay Tree/Images/worst-case-2.png | Bin 0 -> 7076 bytes Splay Tree/Images/worst-case-3.png | Bin 0 -> 9049 bytes Splay Tree/Images/worst-case-4.png | Bin 0 -> 10813 bytes Splay Tree/Images/worst-case-5.png | Bin 0 -> 11827 bytes Splay Tree/Images/worst-case-6.png | Bin 0 -> 35177 bytes Splay Tree/Images/zigzig-wrongrotated.png | Bin 0 -> 38831 bytes 13 files changed, 2 insertions(+) create mode 100644 Splay Tree/Images/SplayTreesWorstCaseExamples.svg create mode 100644 Splay Tree/Images/example-zigzig-1.png create mode 100644 Splay Tree/Images/example-zigzig-2.png create mode 100644 Splay Tree/Images/example-zigzig-3.png create mode 100644 Splay Tree/Images/example-zigzig-4.png create mode 100644 Splay Tree/Images/example-zigzig-5.png create mode 100644 Splay Tree/Images/worst-case-1.png create mode 100644 Splay Tree/Images/worst-case-2.png create mode 100644 Splay Tree/Images/worst-case-3.png create mode 100644 Splay Tree/Images/worst-case-4.png create mode 100644 Splay Tree/Images/worst-case-5.png create mode 100644 Splay Tree/Images/worst-case-6.png create mode 100644 Splay Tree/Images/zigzig-wrongrotated.png diff --git a/Splay Tree/Images/SplayTreesWorstCaseExamples.svg b/Splay Tree/Images/SplayTreesWorstCaseExamples.svg new file mode 100644 index 000000000..c07312af2 --- /dev/null +++ b/Splay Tree/Images/SplayTreesWorstCaseExamples.svg @@ -0,0 +1,2 @@ + +
1
1
2
2
1
1
2
2
1
1
2
2
3
3
1
1
2
2
3
3
1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
5
5
6
6
7
7
8
8
5
5
6
6
7
7
8
8
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
\ No newline at end of file diff --git a/Splay Tree/Images/example-zigzig-1.png b/Splay Tree/Images/example-zigzig-1.png new file mode 100644 index 0000000000000000000000000000000000000000..48a08c17cf8cdbbf4de565b1ae4339a533f8b562 GIT binary patch literal 32202 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

^3u@V70z)B9iJxD+Z%NK(r?LStzHVG-% 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 G@c#kXNwKB? literal 0 HcmV?d00001 diff --git a/Splay Tree/Images/example-zigzig-3.png b/Splay Tree/Images/example-zigzig-3.png new file mode 100644 index 0000000000000000000000000000000000000000..905b4d4bd2d9638e902358172764e23e29c03da6 GIT binary patch literal 29732 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