Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Queue data structure using array andstack techniques #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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