Add a basic Queue data structure

Implemented as a linked list.
This commit is contained in:
Eryn Wells 2018-11-10 17:40:37 -05:00
parent 4e4b6b9bca
commit 47df42c8e5
4 changed files with 117 additions and 4 deletions

View file

@ -9,6 +9,8 @@
/* Begin PBXBuildFile section */
C018AD33219518080094BE3C /* Terrain2Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C018AD32219518080094BE3C /* Terrain2Tests.swift */; };
C018AD3B219518480094BE3C /* AlgorithmsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C018AD3A219518480094BE3C /* AlgorithmsTests.swift */; };
C018AD4021978E690094BE3C /* Queue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C018AD3F21978E690094BE3C /* Queue.swift */; };
C018AD422197907B0094BE3C /* QueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C018AD412197907B0094BE3C /* QueueTests.swift */; };
C019C8512191CE7100EAD5BB /* Uniforms.m in Sources */ = {isa = PBXBuildFile; fileRef = C019C8502191CE7100EAD5BB /* Uniforms.m */; };
C08C58A0218F46F000EAFC2D /* Algorithms.swift in Sources */ = {isa = PBXBuildFile; fileRef = C08C589F218F46F000EAFC2D /* Algorithms.swift */; };
C08C58A2218F474E00EAFC2D /* TerrainAlgorithms.metal in Sources */ = {isa = PBXBuildFile; fileRef = C08C58A1218F474E00EAFC2D /* TerrainAlgorithms.metal */; };
@ -46,6 +48,8 @@
C018AD32219518080094BE3C /* Terrain2Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Terrain2Tests.swift; sourceTree = "<group>"; };
C018AD34219518080094BE3C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C018AD3A219518480094BE3C /* AlgorithmsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlgorithmsTests.swift; sourceTree = "<group>"; };
C018AD3F21978E690094BE3C /* Queue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Queue.swift; sourceTree = "<group>"; };
C018AD412197907B0094BE3C /* QueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueTests.swift; sourceTree = "<group>"; };
C019C8502191CE7100EAD5BB /* Uniforms.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Uniforms.m; sourceTree = "<group>"; };
C08C589F218F46F000EAFC2D /* Algorithms.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Algorithms.swift; sourceTree = "<group>"; };
C08C58A1218F474E00EAFC2D /* TerrainAlgorithms.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = TerrainAlgorithms.metal; sourceTree = "<group>"; };
@ -107,6 +111,7 @@
children = (
C018AD32219518080094BE3C /* Terrain2Tests.swift */,
C018AD3A219518480094BE3C /* AlgorithmsTests.swift */,
C018AD412197907B0094BE3C /* QueueTests.swift */,
C018AD34219518080094BE3C /* Info.plist */,
);
path = Terrain2Tests;
@ -176,6 +181,7 @@
C0C15AB6218E2A90007494E2 /* Renderer.swift */,
C0C15AC5218E32B2007494E2 /* Terrain.swift */,
C08C589F218F46F000EAFC2D /* Algorithms.swift */,
C018AD3F21978E690094BE3C /* Queue.swift */,
C018AD3E219728890094BE3C /* Shaders */,
C0C15ABA218E2A90007494E2 /* ShaderTypes.h */,
C019C8502191CE7100EAD5BB /* Uniforms.m */,
@ -318,6 +324,7 @@
buildActionMask = 2147483647;
files = (
C018AD33219518080094BE3C /* Terrain2Tests.swift in Sources */,
C018AD422197907B0094BE3C /* QueueTests.swift in Sources */,
C018AD3B219518480094BE3C /* AlgorithmsTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -346,6 +353,7 @@
C0C15AB7218E2A90007494E2 /* Renderer.swift in Sources */,
C0C15AB3218E2A90007494E2 /* AppDelegate.swift in Sources */,
C019C8512191CE7100EAD5BB /* Uniforms.m in Sources */,
C018AD4021978E690094BE3C /* Queue.swift in Sources */,
C08C58A0218F46F000EAFC2D /* Algorithms.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View file

@ -222,11 +222,11 @@ public class DiamondSquareGenerator: TerrainGenerator {
}
func breadthFirstSearch(visit: (Box) -> (Void)) {
var queue = [self]
while queue.count > 0 {
let box = queue.removeFirst()
var queue = Queue<Box>()
queue.enqueue(item: self)
while let box = queue.dequeue() {
visit(box)
queue.append(contentsOf: box.subdivisions)
queue.enqueue(items: box.subdivisions)
}
}
}

54
Terrain2/Queue.swift Normal file
View file

@ -0,0 +1,54 @@
//
// Queue.swift
// Terrain2
//
// Created by Eryn Wells on 11/10/18.
// Copyright © 2018 Eryn Wells. All rights reserved.
//
import Foundation
struct Queue<Element> {
class Node<Element> {
var item: Element
var next: Node?
init(item i: Element) {
item = i
}
}
var count: Int = 0
var head: Node<Element>?
var tail: Node<Element>?
mutating func enqueue(item: Element) {
let newNode = Node(item: item)
if head == nil {
head = newNode
tail = newNode
} else {
tail!.next = newNode
tail = newNode
}
count += 1
}
mutating func enqueue<S>(items: S) where Element == S.Element, S : Sequence {
for i in items {
enqueue(item: i)
}
}
mutating func dequeue() -> Element? {
guard let oldHead = head else {
return nil
}
head = oldHead.next
if head == nil {
tail = nil
}
count -= 1
return oldHead.item
}
}

View file

@ -0,0 +1,51 @@
//
// QueueTests.swift
// Terrain2Tests
//
// Created by Eryn Wells on 11/10/18.
// Copyright © 2018 Eryn Wells. All rights reserved.
//
import XCTest
@testable import Terrain2
class QueueTests: XCTestCase {
func testEnqueue() {
var queue = Queue<Int>()
queue.enqueue(item: 1)
queue.enqueue(item: 2)
queue.enqueue(item: 3)
XCTAssertEqual(queue.count, 3)
XCTAssertEqual(queue.head?.item, 1)
XCTAssertEqual(queue.head?.next?.item, 2)
XCTAssertEqual(queue.head?.next?.next?.item, 3)
}
func testDequeue() {
var queue = Queue<Int>()
queue.enqueue(item: 1)
queue.enqueue(item: 2)
queue.enqueue(item: 3)
XCTAssertEqual(queue.count, 3)
XCTAssertEqual(queue.head?.item, 1)
XCTAssertEqual(queue.tail?.item, 3)
XCTAssertEqual(queue.dequeue(), 1)
XCTAssertEqual(queue.count, 2)
XCTAssertEqual(queue.head?.item, 2)
XCTAssertEqual(queue.tail?.item, 3)
XCTAssertEqual(queue.dequeue(), 2)
XCTAssertEqual(queue.count, 1)
XCTAssertEqual(queue.head?.item, 3)
XCTAssertEqual(queue.tail?.item, 3)
XCTAssertEqual(queue.dequeue(), 3)
XCTAssertEqual(queue.count, 0)
XCTAssertNil(queue.head)
XCTAssertNil(queue.tail)
}
}