Skip to content

Commit 8ab833a

Browse files
committed
Implemented Queue data structure using array andstack techniques
1 parent 991a536 commit 8ab833a

File tree

6 files changed

+344
-2
lines changed

6 files changed

+344
-2
lines changed

DevKit/DevKit.xcodeproj/project.pbxproj

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,16 @@
4242
205C74EE2135A3D700AF0B52 /* KeyboardObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205C74EB2135A3D700AF0B52 /* KeyboardObserver.swift */; };
4343
205C74EF2135A3D700AF0B52 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205C74ED2135A3D700AF0B52 /* ReusableView.swift */; };
4444
329452415E472FA3C293B641 /* Pods_DevKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DC5340BFE3332A9CE19D779 /* Pods_DevKit.framework */; };
45+
8E54C4352142E91A003207CC /* QueueArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E54C4342142E91A003207CC /* QueueArrayTests.swift */; };
46+
8E54C4372142EA73003207CC /* QueueStackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E54C4362142EA73003207CC /* QueueStackTests.swift */; };
4547
8E8F4AB52138698B00E2FD66 /* LinkedListNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AB42138698B00E2FD66 /* LinkedListNode.swift */; };
4648
8E8F4AB7213869E000E2FD66 /* LinkedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AB6213869E000E2FD66 /* LinkedList.swift */; };
4749
8E8F4ABC2138731500E2FD66 /* LinkedListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4ABB2138731500E2FD66 /* LinkedListTests.swift */; };
4850
8E8F4ABF2139C6E300E2FD66 /* Stack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4ABE2139C6E300E2FD66 /* Stack.swift */; };
4951
8E8F4AC22139C87300E2FD66 /* StackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AC12139C87300E2FD66 /* StackTests.swift */; };
52+
8E8F4AC52141B18A00E2FD66 /* QueueArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */; };
53+
8ED0CAB92141CEAE00F05CD6 /* Queueable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */; };
54+
8ED0CABB2141D14500F05CD6 /* QueueStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0CABA2141D14500F05CD6 /* QueueStack.swift */; };
5055
D7C6243C4F18537B1510C7A1 /* Pods_DevKitUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3939CE1C2FCEB6AE9D5E4974 /* Pods_DevKitUITests.framework */; };
5156
/* End PBXBuildFile section */
5257

@@ -111,11 +116,16 @@
111116
439C165EDA375DDFA28D0AB6 /* Pods-DevKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DevKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-DevKit/Pods-DevKit.release.xcconfig"; sourceTree = "<group>"; };
112117
4DC5340BFE3332A9CE19D779 /* Pods_DevKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DevKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
113118
61E76AB64DDE67385EB88E7F /* Pods-DevKitUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DevKitUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DevKitUITests/Pods-DevKitUITests.debug.xcconfig"; sourceTree = "<group>"; };
119+
8E54C4342142E91A003207CC /* QueueArrayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueArrayTests.swift; sourceTree = "<group>"; };
120+
8E54C4362142EA73003207CC /* QueueStackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueStackTests.swift; sourceTree = "<group>"; };
114121
8E8F4AB42138698B00E2FD66 /* LinkedListNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedListNode.swift; sourceTree = "<group>"; };
115122
8E8F4AB6213869E000E2FD66 /* LinkedList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedList.swift; sourceTree = "<group>"; };
116123
8E8F4ABB2138731500E2FD66 /* LinkedListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedListTests.swift; sourceTree = "<group>"; };
117124
8E8F4ABE2139C6E300E2FD66 /* Stack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stack.swift; sourceTree = "<group>"; };
118125
8E8F4AC12139C87300E2FD66 /* StackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackTests.swift; sourceTree = "<group>"; };
126+
8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueArray.swift; sourceTree = "<group>"; };
127+
8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queueable.swift; sourceTree = "<group>"; };
128+
8ED0CABA2141D14500F05CD6 /* QueueStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueStack.swift; sourceTree = "<group>"; };
119129
9D986637F245DC8CE1CCA9B0 /* Pods-DevKitUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DevKitUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DevKitUITests/Pods-DevKitUITests.release.xcconfig"; sourceTree = "<group>"; };
120130
A70409DC5600E02F5134B243 /* Pods-DevKitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DevKitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DevKitTests/Pods-DevKitTests.debug.xcconfig"; sourceTree = "<group>"; };
121131
AA8FB83E8BE3E5509A2577E0 /* Pods_DevKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DevKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -485,11 +495,21 @@
485495
name = Pods;
486496
sourceTree = "<group>";
487497
};
498+
8E54C4332142E906003207CC /* Queue */ = {
499+
isa = PBXGroup;
500+
children = (
501+
8E54C4342142E91A003207CC /* QueueArrayTests.swift */,
502+
8E54C4362142EA73003207CC /* QueueStackTests.swift */,
503+
);
504+
path = Queue;
505+
sourceTree = "<group>";
506+
};
488507
8E8F4AB22138696E00E2FD66 /* Data Structures */ = {
489508
isa = PBXGroup;
490509
children = (
491-
8E8F4ABD2139C6D800E2FD66 /* Stack */,
492510
8E8F4AB32138697600E2FD66 /* Linked List */,
511+
8E8F4AC32141B17300E2FD66 /* Queue */,
512+
8E8F4ABD2139C6D800E2FD66 /* Stack */,
493513
);
494514
path = "Data Structures";
495515
sourceTree = "<group>";
@@ -514,8 +534,9 @@
514534
8E8F4AB9213872F900E2FD66 /* Data Structures */ = {
515535
isa = PBXGroup;
516536
children = (
517-
8E8F4AC02139C86700E2FD66 /* Stack */,
518537
8E8F4ABA2138730100E2FD66 /* Linked List */,
538+
8E54C4332142E906003207CC /* Queue */,
539+
8E8F4AC02139C86700E2FD66 /* Stack */,
519540
);
520541
path = "Data Structures";
521542
sourceTree = "<group>";
@@ -544,6 +565,16 @@
544565
path = Stack;
545566
sourceTree = "<group>";
546567
};
568+
8E8F4AC32141B17300E2FD66 /* Queue */ = {
569+
isa = PBXGroup;
570+
children = (
571+
8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */,
572+
8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */,
573+
8ED0CABA2141D14500F05CD6 /* QueueStack.swift */,
574+
);
575+
path = Queue;
576+
sourceTree = "<group>";
577+
};
547578
B4EADB9A0901D69BD2E4AFA6 /* Frameworks */ = {
548579
isa = PBXGroup;
549580
children = (
@@ -790,6 +821,7 @@
790821
8E8F4AB7213869E000E2FD66 /* LinkedList.swift in Sources */,
791822
20524724209BB3550067A328 /* StringExtension.swift in Sources */,
792823
205246F0209BA8B40067A328 /* UIScreenExtension.swift in Sources */,
824+
8ED0CAB92141CEAE00F05CD6 /* Queueable.swift in Sources */,
793825
205246F9209BA8B40067A328 /* UICollectionViewExtension.swift in Sources */,
794826
205246FB209BA8B40067A328 /* UITableViewExtension.swift in Sources */,
795827
205C74EF2135A3D700AF0B52 /* ReusableView.swift in Sources */,
@@ -800,6 +832,7 @@
800832
205246FC209BA8B40067A328 /* UINavigationControllerExtension.swift in Sources */,
801833
205246FD209BA8B40067A328 /* UIColorExtension.swift in Sources */,
802834
205246F7209BA8B40067A328 /* UIStackViewExtension.swift in Sources */,
835+
8ED0CABB2141D14500F05CD6 /* QueueStack.swift in Sources */,
803836
205246FF209BA8B40067A328 /* UISearchBarExtension.swift in Sources */,
804837
20524721209BB3240067A328 /* ImagePickerValidator.swift in Sources */,
805838
205246CB209B9D2B0067A328 /* CalendarPermissionsValidator.swift in Sources */,
@@ -808,6 +841,7 @@
808841
205246EF209BA8B40067A328 /* UIScrollViewExtension.swift in Sources */,
809842
205246F8209BA8B40067A328 /* UIImageExtension.swift in Sources */,
810843
205246D5209BA3200067A328 /* TransitioningNavigationViewOptions.swift in Sources */,
844+
8E8F4AC52141B18A00E2FD66 /* QueueArray.swift in Sources */,
811845
8E8F4AB52138698B00E2FD66 /* LinkedListNode.swift in Sources */,
812846
205246D3209B9E8F0067A328 /* TransitioningNavigationView.swift in Sources */,
813847
20524697209B9C250067A328 /* AppDelegate.swift in Sources */,
@@ -823,6 +857,8 @@
823857
buildActionMask = 2147483647;
824858
files = (
825859
8E8F4AC22139C87300E2FD66 /* StackTests.swift in Sources */,
860+
8E54C4352142E91A003207CC /* QueueArrayTests.swift in Sources */,
861+
8E54C4372142EA73003207CC /* QueueStackTests.swift in Sources */,
826862
8E8F4ABC2138731500E2FD66 /* LinkedListTests.swift in Sources */,
827863
);
828864
runOnlyForDeploymentPostprocessing = 0;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//
2+
// QueueArray.swift
3+
// DevKit
4+
//
5+
// Created by Thibault Klein on 9/6/18.
6+
// Copyright © 2018 Jonathan Samudio. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// QueueArray.
12+
/// A queue is a collection of elements following a First-In-First-Out (FIFO) order.
13+
/// This implementation uses an array to store the elements.
14+
///
15+
/// - Note:
16+
/// Use a Queue if you need a sequence ordered as FIFO.
17+
///
18+
/// - The advantage of using an array is its simplicity and relative low memory impact.
19+
/// - The disadvantage is a O(n) complexity every time an element gets dequeued.
20+
/// Very large queues will have a bad performance using QueueArray.
21+
open class QueueArray<T>: Queueable {
22+
public typealias Element = T
23+
24+
// MARK: - Public Properties
25+
26+
/// `true` if the stack is empty. `false` if not.
27+
public var isEmpty: Bool {
28+
return peek() == nil
29+
}
30+
31+
// MARK: - Private Properties
32+
33+
private var storage: [Element] = []
34+
35+
// MARK: - Initialization
36+
37+
public init() { }
38+
39+
// MARK: - Public Functions
40+
// MARK: General Functions
41+
42+
/// Returns the value at the end of the queue.
43+
///
44+
/// - Complexity: O(1)
45+
/// - Returns: The value at the end of the queue.
46+
public func peek() -> Element? {
47+
return storage.last
48+
}
49+
50+
// MARK: Adding Functions
51+
52+
/// Enqueues an element at the beginning of the queue.
53+
///
54+
/// - Complexity: O(1)
55+
/// - Parameter value: The value to enqueue.
56+
public func enqueue(_ value: Element) {
57+
storage.append(value)
58+
}
59+
60+
// MARK: Removing Functions
61+
62+
/// Dequeues the element at the end of the queue.
63+
///
64+
/// - Complexity: O(n)
65+
/// - Returns: The dequeued element.
66+
public func dequeue() -> Element? {
67+
return isEmpty ? nil : storage.removeFirst()
68+
}
69+
70+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//
2+
// QueueStack.swift
3+
// DevKit
4+
//
5+
// Created by Thibault Klein on 9/6/18.
6+
// Copyright © 2018 Jonathan Samudio. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// QueueStack.
12+
/// A queue is a collection of elements following a First-In-First-Out (FIFO) order.
13+
/// This implementation uses two stacks to store the elements.
14+
///
15+
/// - Note:
16+
/// Use a Queue if you need a sequence ordered as FIFO.
17+
///
18+
/// - The advantage of using two stack is constant complexity when enqueueing and dequeueing.
19+
/// QueueStack has better performance when working with large queues than QueueArray.
20+
open class QueueStack<T>: Queueable {
21+
public typealias Element = T
22+
23+
// MARK: - Public Properties
24+
25+
/// `true` if the stack is empty. `false` if not.
26+
public var isEmpty: Bool {
27+
return leftStack.isEmpty && rightStack.isEmpty
28+
}
29+
30+
// MARK: - Private Properties
31+
32+
private var leftStack: [T] = []
33+
private var rightStack: [T] = []
34+
35+
// MARK: - Initialization
36+
37+
public init() { }
38+
39+
// MARK: - Public Functions
40+
// MARK: General Functions
41+
42+
/// Returns the value at the end of the queue.
43+
///
44+
/// - Complexity: O(1)
45+
/// - Returns: The value at the end of the queue.
46+
public func peek() -> T? {
47+
return !leftStack.isEmpty ? leftStack.last : rightStack.first
48+
}
49+
50+
// MARK: Adding Functions
51+
52+
/// Enqueues an element at the beginning of the queue.
53+
///
54+
/// - Complexity: O(1)
55+
/// - Parameter value: The value to enqueue.
56+
public func enqueue(_ value: T) {
57+
rightStack.append(value)
58+
}
59+
60+
// MARK: Removing Functions
61+
62+
/// Dequeues the element at the end of the queue.
63+
///
64+
/// - Complexity: O(1)
65+
/// - Returns: The dequeued element.
66+
public func dequeue() -> T? {
67+
if leftStack.isEmpty {
68+
leftStack = rightStack.reversed()
69+
rightStack.removeAll()
70+
}
71+
72+
return leftStack.popLast()
73+
}
74+
75+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//
2+
// Queueable.swift
3+
// DevKit
4+
//
5+
// Created by Thibault Klein on 9/6/18.
6+
// Copyright © 2018 Jonathan Samudio. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Defines how a queue can be implemented.
12+
/// There are different techniques you can use to create a queue (array, doubly linked list, ring buffer, double stack...)
13+
/// that can confirm to this protocol.
14+
public protocol Queueable {
15+
associatedtype Element
16+
17+
var isEmpty: Bool { get }
18+
19+
func peek() -> Element?
20+
func enqueue(_ value: Element)
21+
func dequeue() -> Element?
22+
23+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//
2+
// QueueArrayTests.swift
3+
// DevKitTests
4+
//
5+
// Created by Thibault Klein on 9/7/18.
6+
// Copyright © 2018 Jonathan Samudio. All rights reserved.
7+
//
8+
9+
import DevKit
10+
import XCTest
11+
12+
class QueueArrayTests: XCTestCase {
13+
14+
func test_queueArray_IsEmpty_EmptyList() {
15+
// Given
16+
let queue = QueueArray<Int>()
17+
// Then
18+
XCTAssertTrue(queue.isEmpty)
19+
}
20+
21+
func test_queueArray_IsEmpty_NonEmptyList() {
22+
// Given
23+
let queue = QueueArray<Int>()
24+
// When
25+
queue.enqueue(1)
26+
// Then
27+
XCTAssertFalse(queue.isEmpty)
28+
}
29+
30+
func test_queueArray_Peek_EmptyList() {
31+
// Given
32+
let queue = QueueArray<Int>()
33+
// Then
34+
XCTAssertNil(queue.peek())
35+
}
36+
37+
func test_queueArray_Enqueue() {
38+
// Given
39+
let queue = QueueArray<Int>()
40+
XCTAssertNil(queue.peek())
41+
// When
42+
queue.enqueue(1)
43+
// Then
44+
XCTAssertEqual(queue.peek()!, 1)
45+
}
46+
47+
func test_queueArray_Dequeue_EmptyList() {
48+
// Given
49+
let queue = QueueArray<Int>()
50+
XCTAssertNil(queue.peek())
51+
// When
52+
queue.enqueue(1)
53+
// Then
54+
XCTAssertEqual(queue.dequeue()!, 1)
55+
}
56+
57+
func test_queueArray_Dequeue() {
58+
// Given
59+
let queue = QueueArray<Int>()
60+
XCTAssertNil(queue.peek())
61+
// When
62+
queue.enqueue(1)
63+
queue.enqueue(2)
64+
queue.enqueue(3)
65+
// Then
66+
XCTAssertEqual(queue.dequeue()!, 1)
67+
}
68+
69+
}

0 commit comments

Comments
 (0)