forked from kodecocodes/swift-algorithm-club
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
889 additions
and
1 deletion.
There are no files selected for viewing
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
//: Playground - noun: a place where people can play | ||
|
||
import Foundation | ||
|
||
|
||
// *** Simple but inefficient version of quicksort *** | ||
|
||
func quicksort<T: Comparable>(a: [T]) -> [T] { | ||
if a.count <= 1 { | ||
return a | ||
} else { | ||
let pivot = a[a.count/2] | ||
let less = a.filter { $0 < pivot } | ||
let equal = a.filter { $0 == pivot } | ||
let greater = a.filter { $0 > pivot } | ||
|
||
// Uncomment this following line to see in detail what the | ||
// pivot is in each step and how the subarrays are partitioned. | ||
//print(pivot, less, equal, greater) | ||
|
||
return quicksort(less) + equal + quicksort(greater) | ||
} | ||
} | ||
|
||
let list1 = [ 10, 0, 3, 9, 2, 14, 8, 27, 1, 5, 8, -1, 26 ] | ||
quicksort(list1) | ||
|
||
|
||
|
||
// *** Using Lomuto partitioning *** | ||
|
||
/* | ||
Lomuto's partitioning algorithm. | ||
|
||
The return value is the index of the pivot element in the new array. The left | ||
partition is [low...p-1]; the right partition is [p+1...high], where p is the | ||
return value. | ||
*/ | ||
func partitionLomuto<T: Comparable>(inout a: [T], low: Int, high: Int) -> Int { | ||
let pivot = a[high] | ||
|
||
var i = low | ||
for j in low..<high { | ||
if a[j] <= pivot { | ||
(a[i], a[j]) = (a[j], a[i]) | ||
i += 1 | ||
} | ||
} | ||
|
||
(a[i], a[high]) = (a[high], a[i]) | ||
return i | ||
} | ||
|
||
var list2 = [ 10, 0, 3, 9, 2, 14, 26, 27, 1, 5, 8, -1, 8 ] | ||
partitionLomuto(&list2, low: 0, high: list2.count - 1) | ||
list2 | ||
|
||
func quicksortLomuto<T: Comparable>(inout a: [T], low: Int, high: Int) { | ||
if low < high { | ||
let p = partitionLomuto(&a, low: low, high: high) | ||
quicksortLomuto(&a, low: low, high: p - 1) | ||
quicksortLomuto(&a, low: p + 1, high: high) | ||
} | ||
} | ||
|
||
quicksortLomuto(&list2, low: 0, high: list2.count - 1) | ||
|
||
|
||
|
||
// *** Hoare partitioning *** | ||
|
||
/* | ||
Hoare's partitioning scheme. | ||
|
||
The return value is NOT necessarily the index of the pivot element in the | ||
new array. Instead, the array is partitioned into [low...p] and [p+1...high], | ||
where p is the return value. The pivot value is placed somewhere inside one | ||
of the two partitions, but the algorithm doesn't tell you which one or where. | ||
*/ | ||
func partitionHoare<T: Comparable>(inout a: [T], low: Int, high: Int) -> Int { | ||
let pivot = a[low] | ||
var i = low - 1 | ||
var j = high + 1 | ||
|
||
while true { | ||
repeat { j -= 1 } while a[j] > pivot | ||
repeat { i += 1 } while a[i] < pivot | ||
|
||
if i < j { | ||
swap(&a[i], &a[j]) | ||
} else { | ||
return j | ||
} | ||
} | ||
} | ||
|
||
var list3 = [ 8, 0, 3, 9, 2, 14, 10, 27, 1, 5, 8, -1, 26 ] | ||
partitionHoare(&list3, low: 0, high: list3.count - 1) | ||
list3 | ||
|
||
func quicksortHoare<T: Comparable>(inout a: [T], low: Int, high: Int) { | ||
if low < high { | ||
let p = partitionHoare(&a, low: low, high: high) | ||
quicksortHoare(&a, low: low, high: p) | ||
quicksortHoare(&a, low: p + 1, high: high) | ||
} | ||
} | ||
|
||
quicksortHoare(&list3, low: 0, high: list3.count - 1) | ||
|
||
|
||
|
||
// *** Randomized sorting *** | ||
|
||
/* Returns a random integer in the range min...max, inclusive. */ | ||
public func random(min min: Int, max: Int) -> Int { | ||
assert(min < max) | ||
return min + Int(arc4random_uniform(UInt32(max - min + 1))) | ||
} | ||
|
||
func quicksortRandom<T: Comparable>(inout a: [T], low: Int, high: Int) { | ||
if low < high { | ||
let pivotIndex = random(min: low, max: high) | ||
(a[pivotIndex], a[high]) = (a[high], a[pivotIndex]) | ||
|
||
let p = partitionLomuto(&a, low: low, high: high) | ||
quicksortRandom(&a, low: low, high: p - 1) | ||
quicksortRandom(&a, low: p + 1, high: high) | ||
} | ||
} | ||
|
||
var list4 = [ 10, 0, 3, 9, 2, 14, 8, 27, 1, 5, 8, -1, 26 ] | ||
quicksortRandom(&list4, low: 0, high: list4.count - 1) | ||
list4 | ||
|
||
|
||
|
||
// *** Dutch national flag partioning *** | ||
|
||
/* | ||
Swift's swap() doesn't like it if the items you're trying to swap refer to | ||
the same memory location. This little wrapper simply ignores such swaps. | ||
*/ | ||
public func swap<T>(inout a: [T], _ i: Int, _ j: Int) { | ||
if i != j { | ||
swap(&a[i], &a[j]) | ||
} | ||
} | ||
|
||
/* | ||
Dutch national flag partitioning. | ||
Returns a tuple with the start and end index of the middle area. | ||
*/ | ||
func partitionDutchFlag<T: Comparable>(inout a: [T], low: Int, high: Int, pivotIndex: Int) -> (Int, Int) { | ||
let pivot = a[pivotIndex] | ||
|
||
var smaller = low | ||
var equal = low | ||
var larger = high | ||
|
||
while equal <= larger { | ||
if a[equal] < pivot { | ||
swap(&a, smaller, equal) | ||
smaller += 1 | ||
equal += 1 | ||
} else if a[equal] == pivot { | ||
equal += 1 | ||
} else { | ||
swap(&a, equal, larger) | ||
larger -= 1 | ||
} | ||
} | ||
return (smaller, larger) | ||
} | ||
|
||
var list5 = [ 10, 0, 3, 9, 2, 14, 8, 27, 1, 5, 8, -1, 26 ] | ||
partitionDutchFlag(&list5, low: 0, high: list5.count - 1, pivotIndex: 10) | ||
list5 | ||
|
||
func quicksortDutchFlag<T: Comparable>(inout a: [T], low: Int, high: Int) { | ||
if low < high { | ||
let pivotIndex = random(min: low, max: high) | ||
let (p, q) = partitionDutchFlag(&a, low: low, high: high, pivotIndex: pivotIndex) | ||
quicksortDutchFlag(&a, low: low, high: p - 1) | ||
quicksortDutchFlag(&a, low: q + 1, high: high) | ||
} | ||
} | ||
|
||
quicksortDutchFlag(&list5, low: 0, high: list5.count - 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
<playground version='5.0' target-platform='osx'> | ||
<timeline fileName='timeline.xctimeline'/> | ||
</playground> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
Oops, something went wrong.