dsa_visualizer 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,14 +3,337 @@ module DSAVisualizer
3
3
  class Heap
4
4
  def self.learn_min
5
5
  Visualizer.print_header("MIN HEAP - Complete Binary Tree")
6
- puts "\n📚 Coming soon: Heap property, heapify, extract-min"
7
- puts "Topics: Array representation, priority queue implementation"
6
+
7
+ puts "\n📖 CONCEPT:"
8
+ puts "A Min Heap is a complete binary tree where:"
9
+ puts "• Parent is always smaller than its children"
10
+ puts "• Root contains the minimum element"
11
+ puts "• Implemented using array for efficiency"
12
+ puts "• Used in priority queues, heap sort, and graph algorithms"
13
+
14
+ puts "\n⏱️ TIME COMPLEXITY:"
15
+ puts "• Insert: O(log n)"
16
+ puts "• Extract Min: O(log n)"
17
+ puts "• Get Min: O(1)"
18
+ puts "• Build Heap: O(n)"
19
+
20
+ puts "\n💾 SPACE COMPLEXITY: O(n)"
21
+
22
+ demonstrate_min_heap
23
+ demonstrate_operations
24
+ show_array_representation
25
+ show_ruby_vs_cpp
26
+ show_practice_problems
8
27
  end
9
28
 
10
29
  def self.learn_max
11
30
  Visualizer.print_header("MAX HEAP - Complete Binary Tree")
12
- puts "\n📚 Coming soon: Max heap operations"
13
- puts "Topics: Heap sort, building heap in O(n)"
31
+
32
+ puts "\n📖 CONCEPT:"
33
+ puts "A Max Heap is a complete binary tree where:"
34
+ puts "• Parent is always larger than its children"
35
+ puts "• Root contains the maximum element"
36
+ puts "• Same structure as min heap, opposite ordering"
37
+ puts "• Used in heap sort and finding kth largest element"
38
+
39
+ puts "\n⏱️ TIME COMPLEXITY:"
40
+ puts "• Insert: O(log n)"
41
+ puts "• Extract Max: O(log n)"
42
+ puts "• Get Max: O(1)"
43
+ puts "• Build Heap: O(n)"
44
+
45
+ puts "\n💾 SPACE COMPLEXITY: O(n)"
46
+
47
+ demonstrate_max_heap
48
+ end
49
+
50
+ def self.demonstrate_min_heap
51
+ puts "\n" + "="*60
52
+ puts "DEMONSTRATION: Min Heap Operations"
53
+ puts "="*60
54
+
55
+ heap = MinHeapImplementation.new
56
+ values = [10, 20, 5, 30, 15, 3]
57
+
58
+ puts "\nInserting: #{values.join(', ')}"
59
+ values.each do |val|
60
+ heap.insert(val)
61
+ puts "Inserted #{val}, Min: #{heap.peek}"
62
+ end
63
+
64
+ puts "\n📊 Heap Structure:"
65
+ puts " 3"
66
+ puts " / \\"
67
+ puts " 15 5"
68
+ puts " / \\ /"
69
+ puts " 30 20 10"
70
+
71
+ puts "\nArray representation: #{heap.to_a.inspect}"
72
+ end
73
+
74
+ def self.demonstrate_max_heap
75
+ puts "\n" + "="*60
76
+ puts "DEMONSTRATION: Max Heap Operations"
77
+ puts "="*60
78
+
79
+ heap = MaxHeapImplementation.new
80
+ values = [10, 20, 5, 30, 15, 3]
81
+
82
+ puts "\nInserting: #{values.join(', ')}"
83
+ values.each { |val| heap.insert(val) }
84
+
85
+ puts "\n📊 Heap Structure:"
86
+ puts " 30"
87
+ puts " / \\"
88
+ puts " 20 10"
89
+ puts " / \\ /"
90
+ puts " 15 5 3"
91
+
92
+ puts "\nExtracting max elements:"
93
+ 3.times { puts "Extracted: #{heap.extract_max}" }
94
+ end
95
+
96
+ def self.demonstrate_operations
97
+ puts "\n" + "="*60
98
+ puts "MIN HEAP OPERATIONS"
99
+ puts "="*60
100
+
101
+ heap = MinHeapImplementation.new
102
+ [10, 20, 5, 30, 15].each { |v| heap.insert(v) }
103
+
104
+ puts "\n1️⃣ PEEK (Get Min):"
105
+ puts "Minimum: #{heap.peek}"
106
+
107
+ puts "\n2️⃣ EXTRACT MIN:"
108
+ puts "Extracted: #{heap.extract_min}"
109
+ puts "New minimum: #{heap.peek}"
110
+
111
+ puts "\n3️⃣ HEAP SORT:"
112
+ sorted = []
113
+ sorted << heap.extract_min until heap.empty?
114
+ puts "Sorted: #{sorted.join(', ')}"
115
+ end
116
+
117
+ def self.show_array_representation
118
+ puts "\n" + "="*60
119
+ puts "ARRAY REPRESENTATION"
120
+ puts "="*60
121
+
122
+ puts "\nFor node at index i:"
123
+ puts "• Left child: 2*i + 1"
124
+ puts "• Right child: 2*i + 2"
125
+ puts "• Parent: (i-1)/2"
126
+
127
+ puts "\nExample: [3, 15, 5, 30, 20, 10]"
128
+ puts "Index: 0 1 2 3 4 5"
129
+ puts ""
130
+ puts "Node 3 (index 0): children at 1 and 2 → 15, 5"
131
+ puts "Node 15 (index 1): children at 3 and 4 → 30, 20"
132
+ puts "Node 30 (index 3): parent at (3-1)/2 = 1 → 15"
133
+ end
134
+
135
+ def self.show_ruby_vs_cpp
136
+ puts "\n" + "="*60
137
+ puts "RUBY vs C++ IMPLEMENTATION"
138
+ puts "="*60
139
+
140
+ puts "\n🔴 RUBY:"
141
+ puts <<~RUBY
142
+ class MinHeap
143
+ def initialize
144
+ @heap = []
145
+ end
146
+
147
+ def insert(val)
148
+ @heap << val
149
+ heapify_up(@heap.size - 1)
150
+ end
151
+
152
+ def extract_min
153
+ return nil if @heap.empty?
154
+ min = @heap[0]
155
+ @heap[0] = @heap.pop
156
+ heapify_down(0) unless @heap.empty?
157
+ min
158
+ end
159
+
160
+ def heapify_up(index)
161
+ parent = (index - 1) / 2
162
+ if parent >= 0 && @heap[index] < @heap[parent]
163
+ @heap[index], @heap[parent] = @heap[parent], @heap[index]
164
+ heapify_up(parent)
165
+ end
166
+ end
167
+ end
168
+ RUBY
169
+
170
+ puts "\n🔵 C++:"
171
+ puts <<~CPP
172
+ #include <vector>
173
+
174
+ class MinHeap {
175
+ std::vector<int> heap;
176
+ public:
177
+ void insert(int val) {
178
+ heap.push_back(val);
179
+ heapifyUp(heap.size() - 1);
180
+ }
181
+
182
+ int extractMin() {
183
+ int min = heap[0];
184
+ heap[0] = heap.back();
185
+ heap.pop_back();
186
+ heapifyDown(0);
187
+ return min;
188
+ }
189
+
190
+ void heapifyUp(int index) {
191
+ int parent = (index - 1) / 2;
192
+ if (parent >= 0 && heap[index] < heap[parent]) {
193
+ swap(heap[index], heap[parent]);
194
+ heapifyUp(parent);
195
+ }
196
+ }
197
+ };
198
+ CPP
199
+ end
200
+
201
+ def self.show_practice_problems
202
+ puts "\n" + "="*60
203
+ puts "PRACTICE PROBLEMS"
204
+ puts "="*60
205
+
206
+ problems = [
207
+ "1. Kth largest element in array",
208
+ "2. Merge K sorted lists",
209
+ "3. Find median from data stream",
210
+ "4. Top K frequent elements",
211
+ "5. Sort nearly sorted array",
212
+ "6. Connect n ropes with minimum cost",
213
+ "7. K closest points to origin",
214
+ "8. Reorganize string (no adjacent duplicates)"
215
+ ]
216
+
217
+ problems.each { |p| puts p }
218
+
219
+ puts "\n💡 TIP: Use max heap for kth smallest, min heap for kth largest!"
220
+ puts "💡 TIP: Building heap from array is O(n), not O(n log n)!"
221
+ end
222
+
223
+ class MinHeapImplementation
224
+ def initialize
225
+ @heap = []
226
+ end
227
+
228
+ def insert(val)
229
+ @heap << val
230
+ heapify_up(@heap.size - 1)
231
+ end
232
+
233
+ def extract_min
234
+ return nil if @heap.empty?
235
+
236
+ min = @heap[0]
237
+ @heap[0] = @heap.pop
238
+ heapify_down(0) unless @heap.empty?
239
+ min
240
+ end
241
+
242
+ def peek
243
+ @heap[0]
244
+ end
245
+
246
+ def empty?
247
+ @heap.empty?
248
+ end
249
+
250
+ def size
251
+ @heap.size
252
+ end
253
+
254
+ def to_a
255
+ @heap.dup
256
+ end
257
+
258
+ private
259
+
260
+ def heapify_up(index)
261
+ return if index == 0
262
+
263
+ parent = (index - 1) / 2
264
+ if @heap[index] < @heap[parent]
265
+ @heap[index], @heap[parent] = @heap[parent], @heap[index]
266
+ heapify_up(parent)
267
+ end
268
+ end
269
+
270
+ def heapify_down(index)
271
+ left = 2 * index + 1
272
+ right = 2 * index + 2
273
+ smallest = index
274
+
275
+ smallest = left if left < @heap.size && @heap[left] < @heap[smallest]
276
+ smallest = right if right < @heap.size && @heap[right] < @heap[smallest]
277
+
278
+ if smallest != index
279
+ @heap[index], @heap[smallest] = @heap[smallest], @heap[index]
280
+ heapify_down(smallest)
281
+ end
282
+ end
283
+ end
284
+
285
+ class MaxHeapImplementation
286
+ def initialize
287
+ @heap = []
288
+ end
289
+
290
+ def insert(val)
291
+ @heap << val
292
+ heapify_up(@heap.size - 1)
293
+ end
294
+
295
+ def extract_max
296
+ return nil if @heap.empty?
297
+
298
+ max = @heap[0]
299
+ @heap[0] = @heap.pop
300
+ heapify_down(0) unless @heap.empty?
301
+ max
302
+ end
303
+
304
+ def peek
305
+ @heap[0]
306
+ end
307
+
308
+ def empty?
309
+ @heap.empty?
310
+ end
311
+
312
+ private
313
+
314
+ def heapify_up(index)
315
+ return if index == 0
316
+
317
+ parent = (index - 1) / 2
318
+ if @heap[index] > @heap[parent]
319
+ @heap[index], @heap[parent] = @heap[parent], @heap[index]
320
+ heapify_up(parent)
321
+ end
322
+ end
323
+
324
+ def heapify_down(index)
325
+ left = 2 * index + 1
326
+ right = 2 * index + 2
327
+ largest = index
328
+
329
+ largest = left if left < @heap.size && @heap[left] > @heap[largest]
330
+ largest = right if right < @heap.size && @heap[right] > @heap[largest]
331
+
332
+ if largest != index
333
+ @heap[index], @heap[largest] = @heap[largest], @heap[index]
334
+ heapify_down(largest)
335
+ end
336
+ end
14
337
  end
15
338
  end
16
339
  end
@@ -3,8 +3,220 @@ module DSAVisualizer
3
3
  class PriorityQueue
4
4
  def self.learn
5
5
  Visualizer.print_header("PRIORITY QUEUE - Heap-Based Queue")
6
- puts "\n📚 Coming soon: Priority-based dequeue"
7
- puts "Topics: Min/max heap implementation, applications in scheduling"
6
+
7
+ puts "\n📖 CONCEPT:"
8
+ puts "A Priority Queue is an abstract data type where:"
9
+ puts "• Each element has a priority"
10
+ puts "• Higher priority elements are dequeued first"
11
+ puts "• Typically implemented using heaps"
12
+ puts "• Used in scheduling, graph algorithms (Dijkstra, Prim)"
13
+
14
+ puts "\n⏱️ TIME COMPLEXITY:"
15
+ puts "• Insert: O(log n)"
16
+ puts "• Extract Max/Min: O(log n)"
17
+ puts "• Peek: O(1)"
18
+ puts "• Build: O(n)"
19
+
20
+ puts "\n💾 SPACE COMPLEXITY: O(n)"
21
+
22
+ demonstrate_priority_queue
23
+ demonstrate_applications
24
+ show_ruby_vs_cpp
25
+ show_practice_problems
26
+ end
27
+
28
+ def self.demonstrate_priority_queue
29
+ puts "\n" + "="*60
30
+ puts "DEMONSTRATION: Priority Queue Operations"
31
+ puts "="*60
32
+
33
+ pq = PriorityQueueImplementation.new
34
+
35
+ puts "\nInserting tasks with priorities:"
36
+ tasks = [
37
+ { task: "Email", priority: 2 },
38
+ { task: "Meeting", priority: 5 },
39
+ { task: "Coffee", priority: 1 },
40
+ { task: "Deadline", priority: 10 },
41
+ { task: "Lunch", priority: 3 }
42
+ ]
43
+
44
+ tasks.each do |t|
45
+ pq.insert(t[:task], t[:priority])
46
+ puts "Added: #{t[:task]} (priority: #{t[:priority]})"
47
+ end
48
+
49
+ puts "\n📊 Processing by priority (highest first):"
50
+ until pq.empty?
51
+ task, priority = pq.extract_max
52
+ puts "Processing: #{task} (priority: #{priority})"
53
+ end
54
+ end
55
+
56
+ def self.demonstrate_applications
57
+ puts "\n" + "="*60
58
+ puts "REAL-WORLD APPLICATIONS"
59
+ puts "="*60
60
+
61
+ puts "\n1️⃣ CPU SCHEDULING:"
62
+ puts "Process with highest priority gets CPU time first"
63
+
64
+ puts "\n2️⃣ DIJKSTRA'S ALGORITHM:"
65
+ puts "Always process vertex with minimum distance"
66
+
67
+ puts "\n3️⃣ HUFFMAN CODING:"
68
+ puts "Build tree by merging nodes with lowest frequency"
69
+
70
+ puts "\n4️⃣ EVENT-DRIVEN SIMULATION:"
71
+ puts "Process events in chronological order"
72
+
73
+ puts "\n5️⃣ LOAD BALANCING:"
74
+ puts "Assign tasks to least loaded server"
75
+
76
+ puts "\n6️⃣ A* PATHFINDING:"
77
+ puts "Explore nodes with best estimated cost first"
78
+ end
79
+
80
+ def self.show_ruby_vs_cpp
81
+ puts "\n" + "="*60
82
+ puts "RUBY vs C++ IMPLEMENTATION"
83
+ puts "="*60
84
+
85
+ puts "\n🔴 RUBY:"
86
+ puts <<~RUBY
87
+ class PriorityQueue
88
+ def initialize
89
+ @heap = []
90
+ end
91
+
92
+ def insert(item, priority)
93
+ @heap << [item, priority]
94
+ heapify_up(@heap.size - 1)
95
+ end
96
+
97
+ def extract_max
98
+ return nil if @heap.empty?
99
+ max = @heap[0]
100
+ @heap[0] = @heap.pop
101
+ heapify_down(0) unless @heap.empty?
102
+ max
103
+ end
104
+
105
+ def heapify_up(index)
106
+ parent = (index - 1) / 2
107
+ if parent >= 0 && @heap[index][1] > @heap[parent][1]
108
+ @heap[index], @heap[parent] = @heap[parent], @heap[index]
109
+ heapify_up(parent)
110
+ end
111
+ end
112
+ end
113
+ RUBY
114
+
115
+ puts "\n🔵 C++:"
116
+ puts <<~CPP
117
+ #include <queue>
118
+ #include <vector>
119
+
120
+ // Using STL priority_queue (max heap by default)
121
+ std::priority_queue<int> pq;
122
+ pq.push(10);
123
+ pq.push(30);
124
+ pq.push(20);
125
+ int max = pq.top(); // 30
126
+ pq.pop();
127
+
128
+ // Min heap version
129
+ std::priority_queue<int, std::vector<int>, std::greater<int>> minPQ;
130
+
131
+ // Custom comparator
132
+ struct Task {
133
+ string name;
134
+ int priority;
135
+ };
136
+
137
+ auto cmp = [](Task a, Task b) { return a.priority < b.priority; };
138
+ std::priority_queue<Task, std::vector<Task>, decltype(cmp)> taskPQ(cmp);
139
+ CPP
140
+ end
141
+
142
+ def self.show_practice_problems
143
+ puts "\n" + "="*60
144
+ puts "PRACTICE PROBLEMS"
145
+ puts "="*60
146
+
147
+ problems = [
148
+ "1. Kth largest element in stream",
149
+ "2. Merge K sorted arrays",
150
+ "3. Find median in data stream",
151
+ "4. Task scheduler with cooldown",
152
+ "5. Meeting rooms II (min rooms needed)",
153
+ "6. Top K frequent words",
154
+ "7. Reorganize string",
155
+ "8. Minimum cost to connect sticks"
156
+ ]
157
+
158
+ problems.each { |p| puts p }
159
+
160
+ puts "\n💡 TIP: Use min heap when you need smallest, max heap for largest!"
161
+ puts "💡 TIP: Priority queue is perfect for 'Kth largest/smallest' problems"
162
+ end
163
+
164
+ class PriorityQueueImplementation
165
+ def initialize
166
+ @heap = [] # Array of [item, priority] pairs
167
+ end
168
+
169
+ def insert(item, priority)
170
+ @heap << [item, priority]
171
+ heapify_up(@heap.size - 1)
172
+ end
173
+
174
+ def extract_max
175
+ return nil if @heap.empty?
176
+
177
+ max = @heap[0]
178
+ @heap[0] = @heap.pop
179
+ heapify_down(0) unless @heap.empty?
180
+ max
181
+ end
182
+
183
+ def peek
184
+ @heap[0]
185
+ end
186
+
187
+ def empty?
188
+ @heap.empty?
189
+ end
190
+
191
+ def size
192
+ @heap.size
193
+ end
194
+
195
+ private
196
+
197
+ def heapify_up(index)
198
+ return if index == 0
199
+
200
+ parent = (index - 1) / 2
201
+ if @heap[index][1] > @heap[parent][1]
202
+ @heap[index], @heap[parent] = @heap[parent], @heap[index]
203
+ heapify_up(parent)
204
+ end
205
+ end
206
+
207
+ def heapify_down(index)
208
+ left = 2 * index + 1
209
+ right = 2 * index + 2
210
+ largest = index
211
+
212
+ largest = left if left < @heap.size && @heap[left][1] > @heap[largest][1]
213
+ largest = right if right < @heap.size && @heap[right][1] > @heap[largest][1]
214
+
215
+ if largest != index
216
+ @heap[index], @heap[largest] = @heap[largest], @heap[index]
217
+ heapify_down(largest)
218
+ end
219
+ end
8
220
  end
9
221
  end
10
222
  end