Skip to content

Commit

Permalink
Implemented Queue data structure using array andstack techniques
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultKlein committed Sep 7, 2018
1 parent 991a536 commit d0cf79b
Show file tree
Hide file tree
Showing 7 changed files with 349 additions and 2 deletions.
5 changes: 5 additions & 0 deletions DevKit.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ Collection of commonly used swift code.
sp.subspec 'Stack' do |ssp|
ssp.source_files = 'DevKit/DevKit/Classes/Data\ Structures/Stack/*'
end

# Queue
sp.subspec 'Queue' do |ssp|
ssp.source_files = 'DevKit/DevKit/Classes/Data\ Structures/Queue/*'
end
end

end
40 changes: 38 additions & 2 deletions DevKit/DevKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@
205C74EE2135A3D700AF0B52 /* KeyboardObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205C74EB2135A3D700AF0B52 /* KeyboardObserver.swift */; };
205C74EF2135A3D700AF0B52 /* ReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 205C74ED2135A3D700AF0B52 /* ReusableView.swift */; };
329452415E472FA3C293B641 /* Pods_DevKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DC5340BFE3332A9CE19D779 /* Pods_DevKit.framework */; };
8E54C4352142E91A003207CC /* QueueArrayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E54C4342142E91A003207CC /* QueueArrayTests.swift */; };
8E54C4372142EA73003207CC /* QueueStackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E54C4362142EA73003207CC /* QueueStackTests.swift */; };
8E8F4AB52138698B00E2FD66 /* LinkedListNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AB42138698B00E2FD66 /* LinkedListNode.swift */; };
8E8F4AB7213869E000E2FD66 /* LinkedList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AB6213869E000E2FD66 /* LinkedList.swift */; };
8E8F4ABC2138731500E2FD66 /* LinkedListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4ABB2138731500E2FD66 /* LinkedListTests.swift */; };
8E8F4ABF2139C6E300E2FD66 /* Stack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4ABE2139C6E300E2FD66 /* Stack.swift */; };
8E8F4AC22139C87300E2FD66 /* StackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AC12139C87300E2FD66 /* StackTests.swift */; };
8E8F4AC52141B18A00E2FD66 /* QueueArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */; };
8ED0CAB92141CEAE00F05CD6 /* Queueable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */; };
8ED0CABB2141D14500F05CD6 /* QueueStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ED0CABA2141D14500F05CD6 /* QueueStack.swift */; };
D7C6243C4F18537B1510C7A1 /* Pods_DevKitUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3939CE1C2FCEB6AE9D5E4974 /* Pods_DevKitUITests.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -111,11 +116,16 @@
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>"; };
4DC5340BFE3332A9CE19D779 /* Pods_DevKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DevKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; };
8E54C4342142E91A003207CC /* QueueArrayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueArrayTests.swift; sourceTree = "<group>"; };
8E54C4362142EA73003207CC /* QueueStackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueStackTests.swift; sourceTree = "<group>"; };
8E8F4AB42138698B00E2FD66 /* LinkedListNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedListNode.swift; sourceTree = "<group>"; };
8E8F4AB6213869E000E2FD66 /* LinkedList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedList.swift; sourceTree = "<group>"; };
8E8F4ABB2138731500E2FD66 /* LinkedListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkedListTests.swift; sourceTree = "<group>"; };
8E8F4ABE2139C6E300E2FD66 /* Stack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stack.swift; sourceTree = "<group>"; };
8E8F4AC12139C87300E2FD66 /* StackTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackTests.swift; sourceTree = "<group>"; };
8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueArray.swift; sourceTree = "<group>"; };
8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queueable.swift; sourceTree = "<group>"; };
8ED0CABA2141D14500F05CD6 /* QueueStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueStack.swift; sourceTree = "<group>"; };
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>"; };
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>"; };
AA8FB83E8BE3E5509A2577E0 /* Pods_DevKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DevKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -485,11 +495,21 @@
name = Pods;
sourceTree = "<group>";
};
8E54C4332142E906003207CC /* Queue */ = {
isa = PBXGroup;
children = (
8E54C4342142E91A003207CC /* QueueArrayTests.swift */,
8E54C4362142EA73003207CC /* QueueStackTests.swift */,
);
path = Queue;
sourceTree = "<group>";
};
8E8F4AB22138696E00E2FD66 /* Data Structures */ = {
isa = PBXGroup;
children = (
8E8F4ABD2139C6D800E2FD66 /* Stack */,
8E8F4AB32138697600E2FD66 /* Linked List */,
8E8F4AC32141B17300E2FD66 /* Queue */,
8E8F4ABD2139C6D800E2FD66 /* Stack */,
);
path = "Data Structures";
sourceTree = "<group>";
Expand All @@ -514,8 +534,9 @@
8E8F4AB9213872F900E2FD66 /* Data Structures */ = {
isa = PBXGroup;
children = (
8E8F4AC02139C86700E2FD66 /* Stack */,
8E8F4ABA2138730100E2FD66 /* Linked List */,
8E54C4332142E906003207CC /* Queue */,
8E8F4AC02139C86700E2FD66 /* Stack */,
);
path = "Data Structures";
sourceTree = "<group>";
Expand Down Expand Up @@ -544,6 +565,16 @@
path = Stack;
sourceTree = "<group>";
};
8E8F4AC32141B17300E2FD66 /* Queue */ = {
isa = PBXGroup;
children = (
8ED0CAB82141CEAE00F05CD6 /* Queueable.swift */,
8E8F4AC42141B18A00E2FD66 /* QueueArray.swift */,
8ED0CABA2141D14500F05CD6 /* QueueStack.swift */,
);
path = Queue;
sourceTree = "<group>";
};
B4EADB9A0901D69BD2E4AFA6 /* Frameworks */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -790,6 +821,7 @@
8E8F4AB7213869E000E2FD66 /* LinkedList.swift in Sources */,
20524724209BB3550067A328 /* StringExtension.swift in Sources */,
205246F0209BA8B40067A328 /* UIScreenExtension.swift in Sources */,
8ED0CAB92141CEAE00F05CD6 /* Queueable.swift in Sources */,
205246F9209BA8B40067A328 /* UICollectionViewExtension.swift in Sources */,
205246FB209BA8B40067A328 /* UITableViewExtension.swift in Sources */,
205C74EF2135A3D700AF0B52 /* ReusableView.swift in Sources */,
Expand All @@ -800,6 +832,7 @@
205246FC209BA8B40067A328 /* UINavigationControllerExtension.swift in Sources */,
205246FD209BA8B40067A328 /* UIColorExtension.swift in Sources */,
205246F7209BA8B40067A328 /* UIStackViewExtension.swift in Sources */,
8ED0CABB2141D14500F05CD6 /* QueueStack.swift in Sources */,
205246FF209BA8B40067A328 /* UISearchBarExtension.swift in Sources */,
20524721209BB3240067A328 /* ImagePickerValidator.swift in Sources */,
205246CB209B9D2B0067A328 /* CalendarPermissionsValidator.swift in Sources */,
Expand All @@ -808,6 +841,7 @@
205246EF209BA8B40067A328 /* UIScrollViewExtension.swift in Sources */,
205246F8209BA8B40067A328 /* UIImageExtension.swift in Sources */,
205246D5209BA3200067A328 /* TransitioningNavigationViewOptions.swift in Sources */,
8E8F4AC52141B18A00E2FD66 /* QueueArray.swift in Sources */,
8E8F4AB52138698B00E2FD66 /* LinkedListNode.swift in Sources */,
205246D3209B9E8F0067A328 /* TransitioningNavigationView.swift in Sources */,
20524697209B9C250067A328 /* AppDelegate.swift in Sources */,
Expand All @@ -823,6 +857,8 @@
buildActionMask = 2147483647;
files = (
8E8F4AC22139C87300E2FD66 /* StackTests.swift in Sources */,
8E54C4352142E91A003207CC /* QueueArrayTests.swift in Sources */,
8E54C4372142EA73003207CC /* QueueStackTests.swift in Sources */,
8E8F4ABC2138731500E2FD66 /* LinkedListTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
70 changes: 70 additions & 0 deletions DevKit/DevKit/Classes/Data Structures/Queue/QueueArray.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// QueueArray.swift
// DevKit
//
// Created by Thibault Klein on 9/6/18.
// Copyright © 2018 Jonathan Samudio. All rights reserved.
//

import Foundation

/// QueueArray.
/// A queue is a collection of elements following a First-In-First-Out (FIFO) order.
/// This implementation uses an array to store the elements.
///
/// - Note:
/// Use a Queue if you need a sequence ordered as FIFO.
///
/// - The advantage of using an array is its simplicity and relative low memory impact.
/// - The disadvantage is a O(n) complexity every time an element gets dequeued.
/// Very large queues will have a bad performance using QueueArray.
open class QueueArray<T>: Queueable {
public typealias Element = T

// MARK: - Public Properties

/// `true` if the stack is empty. `false` if not.
public var isEmpty: Bool {
return peek() == nil
}

// MARK: - Private Properties

private var storage: [Element] = []

// MARK: - Initialization

public init() { }

// MARK: - Public Functions
// MARK: General Functions

/// Returns the value at the end of the queue.
///
/// - Complexity: O(1)
/// - Returns: The value at the end of the queue.
public func peek() -> Element? {
return storage.last
}

// MARK: Adding Functions

/// Enqueues an element at the beginning of the queue.
///
/// - Complexity: O(1)
/// - Parameter value: The value to enqueue.
public func enqueue(_ value: Element) {
storage.append(value)
}

// MARK: Removing Functions

/// Dequeues the element at the end of the queue.
///
/// - Complexity: O(n)
/// - Returns: The dequeued element.
public func dequeue() -> Element? {
return isEmpty ? nil : storage.removeFirst()
}

}
75 changes: 75 additions & 0 deletions DevKit/DevKit/Classes/Data Structures/Queue/QueueStack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// QueueStack.swift
// DevKit
//
// Created by Thibault Klein on 9/6/18.
// Copyright © 2018 Jonathan Samudio. All rights reserved.
//

import Foundation

/// QueueStack.
/// A queue is a collection of elements following a First-In-First-Out (FIFO) order.
/// This implementation uses two stacks to store the elements.
///
/// - Note:
/// Use a Queue if you need a sequence ordered as FIFO.
///
/// - The advantage of using two stack is constant complexity when enqueueing and dequeueing.
/// QueueStack has better performance when working with large queues than QueueArray.
open class QueueStack<T>: Queueable {
public typealias Element = T

// MARK: - Public Properties

/// `true` if the stack is empty. `false` if not.
public var isEmpty: Bool {
return leftStack.isEmpty && rightStack.isEmpty
}

// MARK: - Private Properties

private var leftStack: [T] = []
private var rightStack: [T] = []

// MARK: - Initialization

public init() { }

// MARK: - Public Functions
// MARK: General Functions

/// Returns the value at the end of the queue.
///
/// - Complexity: O(1)
/// - Returns: The value at the end of the queue.
public func peek() -> T? {
return !leftStack.isEmpty ? leftStack.last : rightStack.first
}

// MARK: Adding Functions

/// Enqueues an element at the beginning of the queue.
///
/// - Complexity: O(1)
/// - Parameter value: The value to enqueue.
public func enqueue(_ value: T) {
rightStack.append(value)
}

// MARK: Removing Functions

/// Dequeues the element at the end of the queue.
///
/// - Complexity: O(1)
/// - Returns: The dequeued element.
public func dequeue() -> T? {
if leftStack.isEmpty {
leftStack = rightStack.reversed()
rightStack.removeAll()
}

return leftStack.popLast()
}

}
23 changes: 23 additions & 0 deletions DevKit/DevKit/Classes/Data Structures/Queue/Queueable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Queueable.swift
// DevKit
//
// Created by Thibault Klein on 9/6/18.
// Copyright © 2018 Jonathan Samudio. All rights reserved.
//

import Foundation

/// Defines how a queue can be implemented.
/// There are different techniques you can use to create a queue (array, doubly linked list, ring buffer, double stack...)
/// that can confirm to this protocol.
public protocol Queueable {
associatedtype Element

var isEmpty: Bool { get }

func peek() -> Element?
func enqueue(_ value: Element)
func dequeue() -> Element?

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// QueueArrayTests.swift
// DevKitTests
//
// Created by Thibault Klein on 9/7/18.
// Copyright © 2018 Jonathan Samudio. All rights reserved.
//

import DevKit
import XCTest

class QueueArrayTests: XCTestCase {

func test_queueArray_IsEmpty_EmptyList() {
// Given
let queue = QueueArray<Int>()
// Then
XCTAssertTrue(queue.isEmpty)
}

func test_queueArray_IsEmpty_NonEmptyList() {
// Given
let queue = QueueArray<Int>()
// When
queue.enqueue(1)
// Then
XCTAssertFalse(queue.isEmpty)
}

func test_queueArray_Peek_EmptyList() {
// Given
let queue = QueueArray<Int>()
// Then
XCTAssertNil(queue.peek())
}

func test_queueArray_Enqueue() {
// Given
let queue = QueueArray<Int>()
XCTAssertNil(queue.peek())
// When
queue.enqueue(1)
// Then
XCTAssertEqual(queue.peek()!, 1)
}

func test_queueArray_Dequeue_EmptyList() {
// Given
let queue = QueueArray<Int>()
XCTAssertNil(queue.peek())
// When
queue.enqueue(1)
// Then
XCTAssertEqual(queue.dequeue()!, 1)
}

func test_queueArray_Dequeue() {
// Given
let queue = QueueArray<Int>()
XCTAssertNil(queue.peek())
// When
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
// Then
XCTAssertEqual(queue.dequeue()!, 1)
}

}
Loading

0 comments on commit d0cf79b

Please sign in to comment.