nove to "index" naming
This commit is contained in:
parent
afc077c8a6
commit
1b3ca7b515
2 changed files with 41 additions and 41 deletions
|
@ -1,13 +1,13 @@
|
||||||
package priority_queue
|
package priority_queue
|
||||||
|
|
||||||
type IndexPriorityQueue[T any] interface {
|
type IndexPriorityQueue[T any] interface {
|
||||||
top() T // get item with biggest priority
|
top() T // get item with biggest priority
|
||||||
topKey() int // get key of an item with biggest priority
|
topIndex() int // get index of an item with biggest priority
|
||||||
remove() T // removes item with the biggest priority
|
remove() T // removes item with the biggest priority
|
||||||
removeKey(key int) T // removes item with specified key
|
removeAtIndex(index int) T // removes item at specified index
|
||||||
insert(key int, item T) // adds item with specified key
|
insert(index int, item T) // adds item at specified index
|
||||||
change(key int, item T) // changes item with specified key
|
change(index int, item T) // changes item at specified index and preserves ordering
|
||||||
contains(key int) bool // checks if key exists in queue
|
contains(index int) bool // checks if item exists at specified index
|
||||||
isEmpty() bool
|
isEmpty() bool
|
||||||
size() int
|
size() int
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,13 @@ type IndexPriorityQueue[T any] interface {
|
||||||
type indexPriorityQueue[T any] struct {
|
type indexPriorityQueue[T any] struct {
|
||||||
n int
|
n int
|
||||||
// unordered items.
|
// unordered items.
|
||||||
// items[key] = item
|
// items[index] = item
|
||||||
items []T
|
items []T
|
||||||
// priority queue. Contains keys for items in priority order.
|
// priority queue. Contains keys for items in priority order.
|
||||||
// items[pq[1]] = item with biggest priority
|
// items[pq[1]] = item with biggest priority
|
||||||
pq []int
|
pq []int
|
||||||
// "reverse" for pq. Maps item key to priority
|
// "reverse" for pq. Maps item index to priority
|
||||||
// qp[key] = priority index, qp[pq[key]] = pq[qp[key]] = key
|
// qp[index] = priority index, qp[pq[index]] = pq[qp[index]] = index
|
||||||
qp []int
|
qp []int
|
||||||
// "less" function. Depending on desired order first element
|
// "less" function. Depending on desired order first element
|
||||||
// not necessary less than a second
|
// not necessary less than a second
|
||||||
|
@ -51,39 +51,39 @@ func (q *indexPriorityQueue[T]) top() T {
|
||||||
return q.items[q.pq[0]]
|
return q.items[q.pq[0]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) topKey() int {
|
func (q *indexPriorityQueue[T]) topIndex() int {
|
||||||
return q.pq[0]
|
return q.pq[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) insert(key int, item T) {
|
func (q *indexPriorityQueue[T]) insert(index int, item T) {
|
||||||
q.pq[q.n] = key
|
q.pq[q.n] = index
|
||||||
q.qp[key] = q.n
|
q.qp[index] = q.n
|
||||||
q.items[key] = item
|
q.items[index] = item
|
||||||
q.swim(q.n)
|
q.swim(q.n)
|
||||||
q.n++
|
q.n++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) remove() T {
|
func (q *indexPriorityQueue[T]) remove() T {
|
||||||
return q.removeKey(q.topKey())
|
return q.removeAtIndex(q.topIndex())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) removeKey(key int) T {
|
func (q *indexPriorityQueue[T]) removeAtIndex(index int) T {
|
||||||
pivot := q.qp[key]
|
pivot := q.qp[index]
|
||||||
q.n--
|
q.n--
|
||||||
q.swap(pivot, q.n)
|
q.swap(pivot, q.n)
|
||||||
q.swim(pivot)
|
q.swim(pivot)
|
||||||
q.sink(pivot)
|
q.sink(pivot)
|
||||||
// TODO: need to remove actual item from items array
|
// TODO: need to remove actual item from items array
|
||||||
// to prevent memory leak
|
// to prevent memory leak
|
||||||
q.qp[key] = -1
|
q.qp[index] = -1
|
||||||
q.pq[q.n] = -1
|
q.pq[q.n] = -1
|
||||||
return q.items[key]
|
return q.items[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) change(key int, item T) {
|
func (q *indexPriorityQueue[T]) change(index int, item T) {
|
||||||
q.items[key] = item
|
q.items[index] = item
|
||||||
q.swim(q.qp[key])
|
q.swim(q.qp[index])
|
||||||
q.sink(q.qp[key])
|
q.sink(q.qp[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pq *indexPriorityQueue[_]) size() int {
|
func (pq *indexPriorityQueue[_]) size() int {
|
||||||
|
@ -94,8 +94,8 @@ func (pq *indexPriorityQueue[_]) isEmpty() bool {
|
||||||
return pq.n == 0
|
return pq.n == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[_]) contains(key int) bool {
|
func (q *indexPriorityQueue[_]) contains(index int) bool {
|
||||||
return q.qp[key] != -1
|
return q.qp[index] != -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *indexPriorityQueue[T]) sink(parent int) {
|
func (q *indexPriorityQueue[T]) sink(parent int) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestNewIPQ(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, 0, q.size())
|
assert.Equal(t, 0, q.size())
|
||||||
assert.Equal(t, true, q.isEmpty())
|
assert.Equal(t, true, q.isEmpty())
|
||||||
assert.Equal(t, -1, q.topKey())
|
assert.Equal(t, -1, q.topIndex())
|
||||||
// TODO: maybe should return nil?
|
// TODO: maybe should return nil?
|
||||||
// assert.Equal(t, 0, q.top())
|
// assert.Equal(t, 0, q.top())
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ func TestMoreIPQInsert(t *testing.T) {
|
||||||
|
|
||||||
pq.insert(1, 10)
|
pq.insert(1, 10)
|
||||||
|
|
||||||
assert.Equal(t, 1, pq.topKey())
|
assert.Equal(t, 1, pq.topIndex())
|
||||||
assert.Equal(t, 10, pq.top())
|
assert.Equal(t, 10, pq.top())
|
||||||
assert.Equal(t, 1, pq.size())
|
assert.Equal(t, 1, pq.size())
|
||||||
assert.Equal(t, true, pq.contains(1))
|
assert.Equal(t, true, pq.contains(1))
|
||||||
|
@ -48,7 +48,7 @@ func TestMoreIPQInsert(t *testing.T) {
|
||||||
|
|
||||||
pq.insert(2, 20)
|
pq.insert(2, 20)
|
||||||
|
|
||||||
assert.Equal(t, 2, pq.topKey())
|
assert.Equal(t, 2, pq.topIndex())
|
||||||
assert.Equal(t, 20, pq.top())
|
assert.Equal(t, 20, pq.top())
|
||||||
assert.Equal(t, 2, pq.size())
|
assert.Equal(t, 2, pq.size())
|
||||||
assert.Equal(t, true, pq.contains(2))
|
assert.Equal(t, true, pq.contains(2))
|
||||||
|
@ -60,7 +60,7 @@ func TestIPQRemove(t *testing.T) {
|
||||||
|
|
||||||
pq.insert(1, 10)
|
pq.insert(1, 10)
|
||||||
|
|
||||||
assert.Equal(t, 1, pq.topKey())
|
assert.Equal(t, 1, pq.topIndex())
|
||||||
assert.Equal(t, 10, pq.top())
|
assert.Equal(t, 10, pq.top())
|
||||||
assert.Equal(t, 1, pq.size())
|
assert.Equal(t, 1, pq.size())
|
||||||
assert.Equal(t, true, pq.contains(1))
|
assert.Equal(t, true, pq.contains(1))
|
||||||
|
@ -68,7 +68,7 @@ func TestIPQRemove(t *testing.T) {
|
||||||
|
|
||||||
pq.insert(2, 20)
|
pq.insert(2, 20)
|
||||||
|
|
||||||
assert.Equal(t, 2, pq.topKey())
|
assert.Equal(t, 2, pq.topIndex())
|
||||||
assert.Equal(t, 20, pq.top())
|
assert.Equal(t, 20, pq.top())
|
||||||
assert.Equal(t, 2, pq.size())
|
assert.Equal(t, 2, pq.size())
|
||||||
assert.Equal(t, true, pq.contains(2))
|
assert.Equal(t, true, pq.contains(2))
|
||||||
|
@ -103,36 +103,36 @@ func TestIPQRemoveAtIndex(t *testing.T) {
|
||||||
pq.insert(4, 40)
|
pq.insert(4, 40)
|
||||||
|
|
||||||
assert.Equal(t, 40, pq.top())
|
assert.Equal(t, 40, pq.top())
|
||||||
assert.Equal(t, 4, pq.topKey())
|
assert.Equal(t, 4, pq.topIndex())
|
||||||
|
|
||||||
// top -> 40 - 30 - 10
|
// top -> 40 - 30 - 10
|
||||||
removed := pq.removeKey(5)
|
removed := pq.removeAtIndex(5)
|
||||||
|
|
||||||
assert.Equal(t, 20, removed)
|
assert.Equal(t, 20, removed)
|
||||||
assert.Equal(t, 40, pq.top())
|
assert.Equal(t, 40, pq.top())
|
||||||
assert.Equal(t, 4, pq.topKey())
|
assert.Equal(t, 4, pq.topIndex())
|
||||||
|
|
||||||
// top -> 30 - 10
|
// top -> 30 - 10
|
||||||
removed = pq.removeKey(4)
|
removed = pq.removeAtIndex(4)
|
||||||
|
|
||||||
assert.Equal(t, 40, removed)
|
assert.Equal(t, 40, removed)
|
||||||
assert.Equal(t, 30, pq.top())
|
assert.Equal(t, 30, pq.top())
|
||||||
assert.Equal(t, 3, pq.topKey())
|
assert.Equal(t, 3, pq.topIndex())
|
||||||
|
|
||||||
// top -> 30 - 20 - 10
|
// top -> 30 - 20 - 10
|
||||||
pq.insert(5, 20)
|
pq.insert(5, 20)
|
||||||
|
|
||||||
assert.Equal(t, 30, pq.top())
|
assert.Equal(t, 30, pq.top())
|
||||||
assert.Equal(t, 3, pq.topKey())
|
assert.Equal(t, 3, pq.topIndex())
|
||||||
|
|
||||||
// top -> 10
|
// top -> 10
|
||||||
removed = pq.removeKey(3)
|
removed = pq.removeAtIndex(3)
|
||||||
assert.Equal(t, 30, removed)
|
assert.Equal(t, 30, removed)
|
||||||
removed = pq.removeKey(5)
|
removed = pq.removeAtIndex(5)
|
||||||
assert.Equal(t, 20, removed)
|
assert.Equal(t, 20, removed)
|
||||||
|
|
||||||
assert.Equal(t, 10, pq.top())
|
assert.Equal(t, 10, pq.top())
|
||||||
assert.Equal(t, 8, pq.topKey())
|
assert.Equal(t, 8, pq.topIndex())
|
||||||
assert.Equal(t, 1, pq.size())
|
assert.Equal(t, 1, pq.size())
|
||||||
assert.Equal(t, false, pq.contains(5))
|
assert.Equal(t, false, pq.contains(5))
|
||||||
assert.Equal(t, false, pq.contains(4))
|
assert.Equal(t, false, pq.contains(4))
|
||||||
|
@ -179,7 +179,7 @@ func TestMultiwayMerge(t *testing.T) {
|
||||||
|
|
||||||
for !pq.isEmpty() {
|
for !pq.isEmpty() {
|
||||||
actual += string(pq.top())
|
actual += string(pq.top())
|
||||||
streamIndex := pq.topKey()
|
streamIndex := pq.topIndex()
|
||||||
pq.remove()
|
pq.remove()
|
||||||
rune, _, err := allStreams[streamIndex].ReadRune()
|
rune, _, err := allStreams[streamIndex].ReadRune()
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
|
|
Loading…
Reference in a new issue