Skip to content

Commit d86ab6e

Browse files
committed
Stack, Queue, Linked List
0 parents  commit d86ab6e

File tree

10 files changed

+382
-0
lines changed

10 files changed

+382
-0
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//: [Previous](@previous)
2+
3+
import Foundation
4+
5+
let list = LinkedList<String>()
6+
list.isEmpty // true
7+
list.first // nil
8+
list.last
9+
10+
list.append("Hello")
11+
list.isEmpty // false
12+
list.first!.value
13+
list.last!.value
14+
15+
list.append("World")
16+
list.first!.value // "Hello"
17+
list.last!.value // "World"
18+
19+
list.first!.previous // nil
20+
list.first!.next!.value // "World"
21+
list.last!.previous!.value // "Hello"
22+
list.last!.next // nil
23+
24+
list.nodeAt(0)!.value // "Hello"
25+
list.nodeAt(1)!.value // "World"
26+
list.nodeAt(2) // nil
27+
28+
list[0] // "Hello"
29+
list[1] // "World"
30+
// list[2] // crash!
31+
32+
list.insert("Swift", atIndex: 1)
33+
list[0] // "Hello"
34+
list[1] // "Swift"
35+
list[2] // "World"
36+
37+
list.remove(list.first!) // "Hello"
38+
list.count // 2
39+
list[0] // "Swift"
40+
list[1] // "World"
41+
42+
//list.removeLast() // "World"
43+
//list.count // 1
44+
//list[0] // "Swift"
45+
//
46+
//list.removeAt(0) // "Swift"
47+
//list.count // 0
48+
49+
list
50+
51+
let list2 = LinkedList<String>()
52+
list2.append("Hello")
53+
list2.append("Swifty")
54+
list2.append("Universe")
55+
56+
let m = list2.map { s in s.characters.count }
57+
m
58+
59+
let f = list2.filter { s in s.characters.count > 5 }
60+
f // [Universe, Swifty]
61+
62+
//: [Next](@next)
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import Foundation
2+
3+
4+
5+
public final class LinkedList<T> {
6+
7+
public typealias Node = LinkedListNode<T>
8+
9+
fileprivate var head: Node?
10+
11+
public init() {}
12+
13+
public var isEmpty: Bool {
14+
return head == nil
15+
}
16+
17+
public var first: Node? {
18+
return head
19+
}
20+
21+
public var last: Node? {
22+
if var node = head {
23+
while case let next? = node.next {
24+
node = next
25+
}
26+
return node
27+
} else {
28+
return nil
29+
}
30+
}
31+
32+
public func append(_ value: T) {
33+
let newNode = Node(value: value)
34+
if let lastNode = last {
35+
newNode.previous = lastNode
36+
lastNode.next = newNode
37+
} else {
38+
head = newNode
39+
}
40+
}
41+
42+
public var count: Int {
43+
if var node = head {
44+
var c = 1
45+
while case let next? = node.next {
46+
node = next
47+
c += 1
48+
}
49+
return c
50+
} else {
51+
return 0
52+
}
53+
}
54+
55+
public func nodeAt(_ index: Int) -> Node? {
56+
if index >= 0 {
57+
var node = head
58+
var i = index
59+
while node != nil {
60+
if i == 0 { return node }
61+
i -= 1
62+
node = node!.next
63+
}
64+
}
65+
return nil
66+
}
67+
68+
public subscript(index: Int) -> T {
69+
let node = nodeAt(index)
70+
assert(node != nil)
71+
return node!.value
72+
}
73+
74+
private func nodesBeforeAndAfter(_ index: Int) -> (Node?, Node?) {
75+
assert(index >= 0)
76+
77+
var i = index
78+
var next = head
79+
var prev: Node?
80+
81+
while next != nil && i > 0 {
82+
i -= 1
83+
prev = next
84+
next = next!.next
85+
}
86+
assert(i == 0)
87+
88+
return (prev, next)
89+
}
90+
91+
public func insert(_ value: T, atIndex index: Int) {
92+
let (prev, next) = nodesBeforeAndAfter(index) // 1
93+
94+
let newNode = Node(value: value) // 2
95+
newNode.previous = prev
96+
newNode.next = next
97+
prev?.next = newNode
98+
next?.previous = newNode
99+
100+
if prev == nil { // 3
101+
head = newNode
102+
}
103+
}
104+
105+
public func removeAll() {
106+
head = nil
107+
}
108+
109+
public func remove(_ node: Node) -> T {
110+
let prev = node.previous
111+
let next = node.next
112+
113+
if let prev = prev {
114+
prev.next = next
115+
} else {
116+
head = next
117+
}
118+
next?.previous = prev
119+
120+
node.previous = nil
121+
node.next = nil
122+
return node.value
123+
}
124+
125+
public func removeLast() -> T {
126+
assert(!isEmpty)
127+
return remove(last!)
128+
}
129+
130+
public func removeAt(_ index: Int) -> T {
131+
let node = nodeAt(index)
132+
assert(node != nil)
133+
return remove(node!)
134+
}
135+
136+
public func reverse() {
137+
var node = head
138+
while let currentNode = node {
139+
node = currentNode.next
140+
swap(&currentNode.next, &currentNode.previous)
141+
head = currentNode
142+
}
143+
}
144+
145+
public func map<U>(transform: (T) -> U) -> LinkedList<U> {
146+
let result = LinkedList<U>()
147+
var node = head
148+
while node != nil {
149+
result.append(transform(node!.value))
150+
node = node!.next
151+
}
152+
return result
153+
}
154+
155+
public func filter(predicate: (T) -> Bool) -> LinkedList<T> {
156+
let result = LinkedList<T>()
157+
var node = head
158+
while node != nil {
159+
if predicate(node!.value) {
160+
result.append(node!.value)
161+
}
162+
node = node!.next
163+
}
164+
return result
165+
}
166+
167+
}
168+
169+
extension LinkedList: CustomStringConvertible {
170+
public var description: String {
171+
var s = "["
172+
var node = head
173+
while node != nil {
174+
s += "\(node!.value)"
175+
node = node!.next
176+
if node != nil { s += ", " }
177+
}
178+
return s + "]"
179+
}
180+
}
181+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Foundation
2+
3+
4+
5+
public class LinkedListNode<T> {
6+
7+
public var value: T
8+
public var next: LinkedListNode?
9+
public weak var previous: LinkedListNode?
10+
11+
public init(value: T) {
12+
self.value = value
13+
}
14+
15+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
public struct Queue<T> {
2+
fileprivate var array = [T?]()
3+
private var head = 0
4+
5+
public var isEmpty: Bool {
6+
return count == 0
7+
}
8+
9+
public var count: Int {
10+
return array.count - head
11+
}
12+
13+
public mutating func enqueue(_ element: T) {
14+
array.append(element)
15+
}
16+
17+
public mutating func dequeue() -> T? {
18+
guard head < array.count, let element = array[head] else { return nil }
19+
20+
array[head] = nil
21+
head += 1
22+
23+
//let percentage = Double(head)/Double(array.count)
24+
//if array.count > 50 && percentage > 0.25 {
25+
if head > 2 {
26+
array.removeFirst(head)
27+
head = 0
28+
}
29+
30+
return element
31+
}
32+
33+
public func peek() -> T? {
34+
if isEmpty {
35+
return nil
36+
} else {
37+
return array[head]
38+
}
39+
}
40+
}
41+
42+
var q = Queue<String>()
43+
q.array // [] empty array
44+
45+
q.enqueue("Ada")
46+
q.enqueue("Steve")
47+
q.enqueue("Tim")
48+
q.array // [{Some "Ada"}, {Some "Steve"}, {Some "Tim"}]
49+
q.count // 3
50+
51+
q.dequeue() // "Ada"
52+
q.array // [nil, {Some "Steve"}, {Some "Tim"}]
53+
q.count // 2
54+
55+
q.dequeue() // "Steve"
56+
q.array // [nil, nil, {Some "Tim"}]
57+
q.count // 1
58+
59+
q.enqueue("Grace")
60+
q.array // [nil, nil, {Some "Tim"}, {Some "Grace"}]
61+
q.count // 2
62+
63+
q.dequeue() // "Tim"
64+
q.array // [{Some "Grace"}]
65+
q.count // 1
66+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public struct Stack<T> {
2+
private var array = [T]()
3+
4+
public var isEmpty: Bool {
5+
return array.isEmpty
6+
}
7+
8+
public var count: Int {
9+
return array.count
10+
}
11+
12+
public mutating func push(_ element: T) {
13+
array.append(element)
14+
}
15+
16+
public mutating func pop() -> T? {
17+
return array.popLast()
18+
}
19+
20+
public func peek() -> T? {
21+
return array.last
22+
}
23+
}
24+
25+
var stack = Stack<Int>()
26+
27+
stack.push(10)
28+
29+
stack.push(3)
30+
31+
stack.push(57)
32+
33+
stack.pop()
34+
35+
stack.pop()

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Swift Algorithm Club!
2+
3+
[Swift Algorithm Club by RayWenderlich](https://github.com/raywenderlich/swift-algorithm-club)

contents.xcplayground

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<playground version='6.0' target-platform='ios' executeOnSourceChanges='false'>
3+
<pages>
4+
<page name='Queue'/>
5+
<page name='Stack'/>
6+
<page name='Linked List'/>
7+
</pages>
8+
</playground>

playground.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Bucket
3+
type = "1"
4+
version = "2.0">
5+
</Bucket>

0 commit comments

Comments
 (0)