Skip to content

Commit 5267c7d

Browse files
Merge pull request #4 from tornikegomareli/feature/DSA
Feature: DSA
2 parents 0ee5ad4 + aa2ead3 commit 5267c7d

File tree

13 files changed

+828
-19
lines changed

13 files changed

+828
-19
lines changed

Exercises/20_dsa_queue/README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Data Structures: Queue
2+
3+
A Queue is a fundamental data structure that follows the First-In-First-Out (FIFO) principle. Think of it like a line at a coffee shop - the first person to join the line is the first person to be served.
4+
5+
## Official Documentation & References
6+
- [Swift Algorithm Club - Queue](https://github.com/kodecocodes/swift-algorithm-club/tree/master/Queue)
7+
- [Apple Developer - Swift Standard Library](https://developer.apple.com/documentation/swift/swift_standard_library)
8+
- [Data Structures in Swift - Queue Implementation](https://www.kodeco.com/books/data-structures-algorithms-in-swift/v4.0/chapters/8-queues)
9+
- [Swift Collections Documentation](https://developer.apple.com/documentation/swift/collections)
10+
- [Generic Programming in Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/generics)
11+
- [Protocol-Oriented Programming](https://developer.apple.com/videos/play/wwdc2015/408/)
12+
13+
## Queue Characteristics
14+
15+
### Key Properties
16+
- **FIFO (First-In-First-Out)**: Elements are processed in the order they were added
17+
- **Two main operations**: Enqueue (add to rear) and Dequeue (remove from front)
18+
- **Linear data structure**: Elements are arranged in a sequence
19+
20+
### When to Use Queues
21+
- Task scheduling (process tasks in order received)
22+
- Breadth-first search algorithms
23+
- Message queuing systems
24+
- Print spoolers
25+
- Call center phone systems
26+
27+
## Core Operations
28+
29+
### Essential Methods
30+
1. **enqueue(_:)** - Add an element to the rear of the queue
31+
2. **dequeue()** - Remove and return the element from the front
32+
3. **peek()** - View the front element without removing it
33+
4. **isEmpty** - Check if the queue has no elements
34+
5. **count** - Get the number of elements in the queue
35+
36+
## Implementation Approaches
37+
38+
### Array-Based Queue
39+
```swift
40+
struct Queue<Element> {
41+
private var elements: [Element] = []
42+
43+
mutating func enqueue(_ element: Element) {
44+
elements.append(element)
45+
}
46+
47+
mutating func dequeue() -> Element? {
48+
guard !elements.isEmpty else { return nil }
49+
return elements.removeFirst()
50+
}
51+
}
52+
```
53+
**Pros**: Simple implementation
54+
**Cons**: O(n) dequeue operation due to array shifting
55+
56+
### Optimized Array-Based Queue
57+
Uses two arrays or a circular buffer to achieve O(1) amortized operations.
58+
59+
### Linked List-Based Queue
60+
Uses nodes with references to achieve true O(1) operations for both enqueue and dequeue.
61+
62+
## Time Complexity
63+
64+
| Operation | Array-Based | Optimized | Linked List |
65+
|-----------|------------|-----------|-------------|
66+
| Enqueue | O(1)* | O(1) | O(1) |
67+
| Dequeue | O(n) | O(1)* | O(1) |
68+
| Peek | O(1) | O(1) | O(1) |
69+
| Space | O(n) | O(n) | O(n) |
70+
71+
*Amortized time complexity
72+
73+
## Exercise Progression
74+
75+
1. **queue1.swift** - Basic Structure
76+
- Create a Queue struct with storage array
77+
- Understand the basic structure
78+
79+
2. **queue2.swift** - Enqueue Operation
80+
- Implement adding elements to the queue
81+
- Understand rear insertion
82+
83+
3. **queue3.swift** - Dequeue Operation
84+
- Implement removing elements from the queue
85+
- Handle empty queue cases
86+
87+
4. **queue4.swift** - Peek and Helper Methods
88+
- Implement peek to view without removing
89+
- Add isEmpty and count properties
90+
91+
5. **queue5.swift** - Generic Queue
92+
- Convert to generic implementation
93+
- Work with any type, not just Int
94+
95+
6. **queue6.swift** - Protocol Conformance
96+
- Make Queue conform to Collection
97+
- Enable iteration and standard collection operations
98+
99+
## Tips for Success
100+
101+
1. **Visualize the Queue**: Draw out the queue operations on paper
102+
2. **Handle Edge Cases**: Always check for empty queue before dequeue/peek
103+
3. **Think About Efficiency**: Consider time complexity of operations
104+
4. **Use Optionals**: Return nil for operations on empty queues
105+
5. **Test Thoroughly**: Try edge cases like single element, empty queue
106+
107+
## Advanced Topics (Beyond These Exercises)
108+
109+
- **Priority Queues**: Elements are dequeued based on priority
110+
- **Deque (Double-ended Queue)**: Can add/remove from both ends
111+
- **Circular Queues**: Fixed-size queue that wraps around
112+
- **Concurrent Queues**: Thread-safe queue implementations
113+
114+
## Real-World Applications
115+
116+
- **iOS Development**: DispatchQueue for managing tasks
117+
- **Networking**: Request queuing and rate limiting
118+
- **Gaming**: Turn-based game mechanics
119+
- **UI**: Animation queues and event handling
120+
121+
## Further Reading
122+
123+
- [Algorithms, 4th Edition - Queues](https://algs4.cs.princeton.edu/13stacks/)
124+
- [Introduction to Algorithms - CLRS](https://mitpress.mit.edu/books/introduction-algorithms-third-edition)
125+
- [Swift Forums - Data Structures Discussion](https://forums.swift.org/c/related-projects/swift-collections/72)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// queue1.swift
2+
//
3+
// Data Structures: Queue - Basic Structure
4+
// A Queue is a FIFO (First-In-First-Out) data structure.
5+
// Like a line at a store - first person in line is first to be served.
6+
//
7+
// Create a basic Queue structure with storage for integers.
8+
9+
import Foundation
10+
11+
// TODO: Define a Queue struct with:
12+
// 1. A property called 'elements' that is an array of Int
13+
// 2. Initialize it as an empty array
14+
15+
struct Queue {
16+
// var elements: ??? = ???
17+
}
18+
19+
func main() {
20+
test("Queue initialization") {
21+
let queue = Queue()
22+
23+
assertEqual(queue.elements.isEmpty, true,
24+
"Queue should be empty when initialized")
25+
assertEqual(queue.elements.count, 0,
26+
"New queue should have 0 elements")
27+
}
28+
29+
test("Queue can store elements array") {
30+
var queue = Queue()
31+
queue.elements = [1, 2, 3]
32+
33+
assertEqual(queue.elements, [1, 2, 3],
34+
"Should be able to set elements directly")
35+
assertEqual(queue.elements.count, 3,
36+
"Queue should have 3 elements")
37+
}
38+
39+
runTests()
40+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// queue2.swift
2+
//
3+
// Data Structures: Queue - Enqueue Operation
4+
// Enqueue adds elements to the rear (end) of the queue.
5+
// This is the "getting in line" operation.
6+
//
7+
// Implement the enqueue method to add elements to the queue.
8+
9+
import Foundation
10+
11+
struct Queue {
12+
var elements: [Int] = []
13+
14+
// TODO: Implement the enqueue method
15+
// 1. It should be a mutating function (modifies the struct)
16+
// 2. Takes an Int parameter called 'element'
17+
// 3. Adds the element to the end of the elements array
18+
19+
// mutating func enqueue(_ element: ???) {
20+
// ???
21+
// }
22+
}
23+
24+
func main() {
25+
test("Enqueue single element") {
26+
var queue = Queue()
27+
queue.enqueue(10)
28+
29+
assertEqual(queue.elements, [10],
30+
"Queue should contain [10] after enqueueing 10")
31+
}
32+
33+
test("Enqueue multiple elements") {
34+
var queue = Queue()
35+
queue.enqueue(1)
36+
queue.enqueue(2)
37+
queue.enqueue(3)
38+
39+
assertEqual(queue.elements, [1, 2, 3],
40+
"Elements should be in order [1, 2, 3]")
41+
assertEqual(queue.elements.count, 3,
42+
"Queue should have 3 elements")
43+
}
44+
45+
test("Enqueue maintains FIFO order") {
46+
var queue = Queue()
47+
queue.enqueue(100)
48+
queue.enqueue(200)
49+
queue.enqueue(300)
50+
51+
assertEqual(queue.elements.first, 100,
52+
"First element should be 100 (first in)")
53+
assertEqual(queue.elements.last, 300,
54+
"Last element should be 300 (last in)")
55+
}
56+
57+
runTests()
58+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// queue3.swift
2+
//
3+
// Data Structures: Queue - Dequeue Operation
4+
// Dequeue removes and returns the element from the front of the queue.
5+
// This is the "being served and leaving the line" operation.
6+
//
7+
// Implement the dequeue method to remove elements from the queue.
8+
9+
import Foundation
10+
11+
struct Queue {
12+
var elements: [Int] = []
13+
14+
mutating func enqueue(_ element: Int) {
15+
elements.append(element)
16+
}
17+
18+
// TODO: Implement the dequeue method
19+
// 1. It should be a mutating function
20+
// 2. Returns an Optional Int (Int?)
21+
// 3. If queue is empty, return nil
22+
// 4. Otherwise, remove and return the first element
23+
24+
// mutating func dequeue() -> ??? {
25+
// guard !elements.??? else { return ??? }
26+
// return elements.???
27+
// }
28+
}
29+
30+
func main() {
31+
test("Dequeue from empty queue") {
32+
var queue = Queue()
33+
let result = queue.dequeue()
34+
35+
assertEqual(result, nil,
36+
"Dequeue from empty queue should return nil")
37+
}
38+
39+
test("Dequeue single element") {
40+
var queue = Queue()
41+
queue.enqueue(42)
42+
43+
let result = queue.dequeue()
44+
assertEqual(result, 42,
45+
"Should dequeue 42")
46+
assertEqual(queue.elements.isEmpty, true,
47+
"Queue should be empty after dequeuing last element")
48+
}
49+
50+
test("Dequeue maintains FIFO order") {
51+
var queue = Queue()
52+
queue.enqueue(1)
53+
queue.enqueue(2)
54+
queue.enqueue(3)
55+
56+
assertEqual(queue.dequeue(), 1, "First dequeue should return 1")
57+
assertEqual(queue.dequeue(), 2, "Second dequeue should return 2")
58+
assertEqual(queue.elements, [3], "Queue should contain [3]")
59+
assertEqual(queue.dequeue(), 3, "Third dequeue should return 3")
60+
assertEqual(queue.dequeue(), nil, "Fourth dequeue should return nil")
61+
}
62+
63+
runTests()
64+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// queue4.swift
2+
//
3+
// Data Structures: Queue - Peek and Helper Methods
4+
// Peek lets you see what's at the front without removing it.
5+
// isEmpty and count are helpful utilities for queue management.
6+
//
7+
// Implement peek, isEmpty, and count for the Queue.
8+
9+
import Foundation
10+
11+
struct Queue {
12+
var elements: [Int] = []
13+
14+
mutating func enqueue(_ element: Int) {
15+
elements.append(element)
16+
}
17+
18+
mutating func dequeue() -> Int? {
19+
guard !elements.isEmpty else { return nil }
20+
return elements.removeFirst()
21+
}
22+
23+
// TODO: Implement peek method
24+
// 1. Returns an Optional Int (Int?)
25+
// 2. Returns the first element without removing it
26+
// 3. Returns nil if queue is empty
27+
28+
// func peek() -> ??? {
29+
// return elements.???
30+
// }
31+
32+
// TODO: Implement isEmpty computed property
33+
// Returns true if the queue has no elements
34+
35+
// var isEmpty: Bool {
36+
// return elements.???
37+
// }
38+
39+
// TODO: Implement count computed property
40+
// Returns the number of elements in the queue
41+
42+
// var count: Int {
43+
// return ???
44+
// }
45+
}
46+
47+
func main() {
48+
test("Peek on empty queue") {
49+
let queue = Queue()
50+
51+
assertEqual(queue.peek(), nil,
52+
"Peek on empty queue should return nil")
53+
}
54+
55+
test("Peek doesn't remove element") {
56+
var queue = Queue()
57+
queue.enqueue(10)
58+
queue.enqueue(20)
59+
60+
assertEqual(queue.peek(), 10, "Peek should return 10")
61+
assertEqual(queue.peek(), 10, "Peek again should still return 10")
62+
assertEqual(queue.elements, [10, 20], "Elements should remain unchanged")
63+
}
64+
65+
test("isEmpty property") {
66+
var queue = Queue()
67+
68+
assertEqual(queue.isEmpty, true, "New queue should be empty")
69+
70+
queue.enqueue(1)
71+
assertEqual(queue.isEmpty, false, "Queue with element should not be empty")
72+
73+
_ = queue.dequeue()
74+
assertEqual(queue.isEmpty, true, "Queue should be empty after dequeuing last element")
75+
}
76+
77+
test("Count property") {
78+
var queue = Queue()
79+
80+
assertEqual(queue.count, 0, "Empty queue should have count 0")
81+
82+
queue.enqueue(1)
83+
assertEqual(queue.count, 1, "Count should be 1")
84+
85+
queue.enqueue(2)
86+
queue.enqueue(3)
87+
assertEqual(queue.count, 3, "Count should be 3")
88+
89+
_ = queue.dequeue()
90+
assertEqual(queue.count, 2, "Count should be 2 after dequeue")
91+
}
92+
93+
runTests()
94+
}

0 commit comments

Comments
 (0)