Преглед изворни кода

Prioq can now remove any element if its position is known

Guillaume Koenig пре 7 година
родитељ
комит
e25b00cee8
1 измењених фајлова са 26 додато и 9 уклоњено
  1. 26 9
      main.go

+ 26 - 9
main.go

@@ -65,6 +65,7 @@ func (rs ByEndtime) Less(i, j int) bool {
65 65
 
66 66
 type Scheduler interface {
67 67
 	Add(*Car)
68
+	RemoveAtIndex(k int) *Car
68 69
 	Pop() *Car
69 70
 }
70 71
 
@@ -76,7 +77,8 @@ type Car struct {
76 77
 	X       int
77 78
 	Y       int
78 79
 
79
-	score int
80
+	score   int
81
+	pqindex int // used for removal in prority queue
80 82
 }
81 83
 
82 84
 func (c *Car) Update(r *Ride) {
@@ -295,31 +297,35 @@ type prioq struct {
295 297
 
296 298
 func (pq *prioq) Add(car *Car) {
297 299
 	pq.bintree = append(pq.bintree, car)
300
+	pq.bintree[len(pq.bintree)-1].pqindex = len(pq.bintree) - 1
298 301
 
299 302
 	// Rebalance tree to respect invariant
300 303
 	var i = len(pq.bintree) - 1
301 304
 	var p = (i - 1) / 2
302 305
 	for p >= 0 && pq.bintree[p].Arrival > pq.bintree[i].Arrival {
303 306
 		pq.bintree[p], pq.bintree[i] = pq.bintree[i], pq.bintree[p]
307
+		pq.bintree[p].pqindex = p
308
+		pq.bintree[i].pqindex = i
304 309
 		i = p
305 310
 		p = (i - 1) / 2
306 311
 	}
307 312
 }
308 313
 
309
-func (pq *prioq) Pop() *Car {
314
+func (pq *prioq) RemoveAtIndex(k int) *Car {
310 315
 	if len(pq.bintree) == 0 {
311 316
 		return nil
312 317
 	}
313 318
 
314
-	if len(pq.bintree) == 1 {
315
-		elem := pq.bintree[0]
316
-		pq.bintree = pq.bintree[:0]
319
+	if k == len(pq.bintree)-1 {
320
+		elem := pq.bintree[k]
321
+		pq.bintree = pq.bintree[:k]
317 322
 		return elem
318 323
 	}
319 324
 
320
-	elem := pq.bintree[0]
321
-	// Put last element at root
322
-	pq.bintree[0] = pq.bintree[len(pq.bintree)-1]
325
+	elem := pq.bintree[k]
326
+	// Put last element at hole
327
+	pq.bintree[k] = pq.bintree[len(pq.bintree)-1]
328
+	pq.bintree[k].pqindex = k
323 329
 	// Remove last element
324 330
 	pq.bintree = pq.bintree[:len(pq.bintree)-1]
325 331
 
@@ -330,7 +336,8 @@ func (pq *prioq) Pop() *Car {
330 336
 
331 337
 	// Rebalance tree to respect invariant
332 338
 	len := len(pq.bintree)
333
-	i, left, right := 0, 0, 0
339
+	i := k
340
+	left, right := 0, 0
334 341
 	for {
335 342
 		left = 2*i + 1
336 343
 		right = 2*i + 2
@@ -340,6 +347,8 @@ func (pq *prioq) Pop() *Car {
340 347
 					break // Inferior to both children
341 348
 				} else {
342 349
 					pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
350
+					pq.bintree[i].pqindex = i
351
+					pq.bintree[left].pqindex = left
343 352
 					i = left
344 353
 				}
345 354
 			} else {
@@ -347,6 +356,8 @@ func (pq *prioq) Pop() *Car {
347 356
 					break // Inferior to both children
348 357
 				} else {
349 358
 					pq.bintree[i], pq.bintree[right] = pq.bintree[right], pq.bintree[i]
359
+					pq.bintree[i].pqindex = i
360
+					pq.bintree[right].pqindex = right
350 361
 					i = right
351 362
 				}
352 363
 			}
@@ -355,6 +366,8 @@ func (pq *prioq) Pop() *Car {
355 366
 				break // Inferior to only child
356 367
 			}
357 368
 			pq.bintree[i], pq.bintree[left] = pq.bintree[left], pq.bintree[i]
369
+			pq.bintree[i].pqindex = i
370
+			pq.bintree[left].pqindex = left
358 371
 			i = left
359 372
 		} else { // No child
360 373
 			break
@@ -365,6 +378,10 @@ func (pq *prioq) Pop() *Car {
365 378
 	return elem
366 379
 }
367 380
 
381
+func (pq *prioq) Pop() *Car {
382
+	return pq.RemoveAtIndex(0)
383
+}
384
+
368 385
 func (pq *prioq) empty() bool {
369 386
 	return len(pq.bintree) == 0
370 387
 }