Skip to main content

Indexed Heap

This package provides a pure-Python implementation of MinHeap and MaxHeap that extend standard heap functionality with support for:

  • Efficient removal of any value.
  • Removal of multiple occurrences of a value in a single operation.
  • Insertion of multiple occurrences of a value in a single operation.
  • Tracking frequency to handle duplicate values.
  • Iteration in sorted order (ascending for MinHeap, descending for MaxHeap) without modifying the heap.
  • Container-like behavior with implementations for len(), in, equality checks, and truthiness.

Features & Time Complexity

Operation Description Time Complexity
insert(value, count=1) Insert a value (or multiple occurrences). If the value already exists, frequency is incremented O(log N) for a new value; O(1) for an existing value
pop() Remove and return the root value (min or max) O(log N)
peek() Return the root value without removing it O(1)
remove(value, *, count=1, strict=True) Remove a value (or multiple occurrences). Removing fewer than the total occurrences is O(1); removing the last occurrence is O(log N)
count(value) Return the frequency of a value O(1)
to_sorted_list() Return a fully sorted list of all values without modifying the heap O(N log N)
len(heap) Number of elements in the heap O(1)
value in heap Membership check O(1)
iter(heap) Iterate over values in sorted order O(N log N)
bool(heap) Check if heap is non-empty O(1)
heap1 == heap2 Check heaps for equality O(N)

Notes:

  • Equality checks (heap1 == heap2) are structural and strict. Heaps with identical values but different insertion orders (resulting in different internal layouts) will not be considered equal.
  • count refers to the number of occurrences to insert or remove from the heap, defaults to 1.

Installation

pip install indexedheap

Quick Reference

Create an empty heap

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap() # Heap is empty.
max_heap = MaxHeap() # Heap is empty.

Create a heap from a list

from indexedheap import MinHeap, MaxHeap

arr = [1,2,3]
min_heap = MinHeap(arr) # Heap contains: [(value: 1, frequency: 1), (value: 2, frequency: 1), (value: 3, frequency: 1)].
max_heap = MaxHeap(arr) # Heap contains: [(value: 3, frequency: 1), (value: 1, frequency: 1), (value: 2, frequency: 1)].

Insert a value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap() # Heap is empty.
min_heap.insert(1) # Heap contains: [(value: 1, frequency: 1)].

max_heap = MaxHeap() # Heap is empty.
max_heap.insert(1) # Heap contains: [(value: 1, frequency: 1)].

Insert a value multiple times

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap() # Heap is empty.
min_heap.insert(1, count=2) # Heap contains: [(value: 1, frequency: 2)].

max_heap = MaxHeap() # Heap is empty.
max_heap.insert(1, count=2) # Heap contains: [(value: 1, frequency: 2)].

Remove a value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1]) # Heap contains: [(value: 1, frequency: 1)].
min_heap.remove(1) # Heap is empty.

max_heap = MaxHeap([1]) # Heap contains: [(value: 1, frequency: 1)].
max_heap.remove(1) # Heap is empty.

Remove multiple occurrences of a value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
min_heap.remove(1, count=2) # Heap is empty.

max_heap = MaxHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
max_heap.remove(1, count=2) # Heap is empty.

Remove all occurrences of a value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
min_heap.remove(1, count=min_heap.count(1)) # Heap is empty.

max_heap = MaxHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
max_heap.remove(1, count=max_heap.count(1)) # Heap is empty.

Optimistically remove a value

The strict flag controls whether removing a non-existent value should raise an error:

  • strict=True (default) -> raise a KeyError if the value isn't in the heap
  • strict=False -> attempt to remove the value (up to the given count, if provided), but do nothing if it isn't present
from indexedheap import MinHeap, MaxHeap

# Value not present — no error
min_heap = MinHeap([]) # Heap is empty.
min_heap.remove(1) # Raises KeyError.
min_heap.remove(1, strict=False) # Heap is empty, no error.

# Value present, but count exceeds frequency — no error
min_heap = MinHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
min_heap.remove(1, count=3) # Raises ValueError.
min_heap.remove(1, count=3, strict=False) # Heap is empty, no error.

# Same for MaxHeap
max_heap = MaxHeap([]) # Heap is empty.
max_heap.remove(1) # Raises KeyError.
max_heap.remove(1, strict=False) # Heap is empty, no error.

max_heap = MaxHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
max_heap.remove(1, count=3) # Raises ValueError.
max_heap.remove(1, count=3, strict=False) # Heap is empty, no error.

Peek root value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 2]) # Heap contains: [(value: 1, frequency: 1), (value: 2, frequency: 1)].
min_heap.peek() # Returns 1; Heap unchanged.

max_heap = MaxHeap([1, 2]) # Heap contains: [(value: 2, frequency: 1), (value: 1, frequency: 1)].
max_heap.peek() # Returns 2; Heap unchanged.

Pop root value

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 2]) # Heap contains: [(value: 1, frequency: 1), (value: 2, frequency: 1)].
min_heap.pop() # Returns 1; Heap contains: [(value: 2, frequency: 1)].

max_heap = MaxHeap([1, 2]) # Heap contains: [(value: 2, frequency: 1), (value: 1, frequency: 1)].
max_heap.pop() # Returns 2; Heap contains: [(value: 1, frequency: 1)].

Get frequency (count) of value

from indexedheap import MinHeap, MaxHeap

# Value present
min_heap = MinHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
min_heap.count(1) # Returns 2; Heap unchanged.

max_heap = MaxHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
max_heap.count(1) # Returns 2; Heap unchanged.

# Value not present
min_heap = MinHeap() # Heap is empty.
min_heap.count(1) # Returns 0; Heap unchanged.

max_heap = MaxHeap() # Heap is empty.
max_heap.count(1) # Returns 0; Heap unchanged.

Get heap size (including duplicates)

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
len(min_heap) # Returns 2; Heap unchanged.

min_heap = MinHeap([1, 2]) # Heap contains: [(value: 1, frequency: 1), (value: 2, frequency: 1)].
len(min_heap) # Returns 2; Heap unchanged.

max_heap = MaxHeap([1, 1]) # Heap contains: [(value: 1, frequency: 2)].
len(max_heap) # Returns 2; Heap unchanged.

max_heap = MaxHeap([1, 2]) # Heap contains: [(value: 2, frequency: 1), (value: 1, frequency: 1)].
len(max_heap) # Returns 2; Heap unchanged.

Iterate heap contents in sorted order

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 3, 2]) # Heap contains: [(value: 1, frequency: 1), (value: 3, frequency: 1), (value: 2, frequency: 1)].
for value in min_heap:
    print(value)
# >>> 1
# >>> 2
# >>> 3
# Iteration yields values in sorted order; Heap unchanged.

max_heap = MaxHeap([1, 3, 2]) # Heap contains: [(value: 3, frequency: 1), (value: 1, frequency: 1), (value: 2, frequency: 1)].
for value in max_heap:
    print(value)
# >>> 3
# >>> 2
# >>> 1
# Iteration yields values in sorted order; Heap unchanged.

Get heap contents as a sorted list

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1, 3, 2]) # Heap contains: [(value: 1, frequency: 1), (value: 3, frequency: 1), (value: 2, frequency: 1)].
min_heap.to_sorted_list() # Returns [1, 2, 3]; Heap unchanged.

max_heap = MaxHeap([1, 3, 2]) # Heap contains: [(value: 3, frequency: 1), (value: 1, frequency: 1), (value: 2, frequency: 1)].
max_heap.to_sorted_list() # Returns [3, 2, 1]; Heap unchanged.

# list(heap) also returns items in sorted order because __iter__ yields items sorted.
list(min_heap)  # Returns [1, 2, 3]; Heap unchanged.
list(max_heap)  # Returns [3, 2, 1]; Heap unchanged.

Test Membership

from indexedheap import MinHeap, MaxHeap

min_heap = MinHeap([1]) # Heap contains: [(value: 1, frequency: 1)].
1 in min_heap # Returns True.
0 in min_heap # Returns False.

max_heap = MaxHeap([1]) # Heap contains: [(value: 1, frequency: 1)].
1 in max_heap # Returns True.
0 in max_heap # Returns False.

Metadata

Release files for indexedheap 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for indexedheap 0.1.1
File Size Uploaded
indexedheap-0.1.1.tar.gz 10.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for indexedheap 0.1.1
File Interpreter ABI Platform
indexedheap-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 19.9 kB

Release files / indexedheap-0.1.1.tar.gz

Download URL indexedheap-0.1.1.tar.gz
Size 10.2 kB
Tags Source
SHA-256 checksum
How to use checksums
e669b6b7aee5e1c0f96d626ba2503c862716485bab48296620ba9f5371e90a5b
BLAKE2b-256 checksum
How to use checksums
389d3876892d8a1185970c35a2f9aedcb4d2781d0ea39ff8a9260121ad26776c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.3

Release files / indexedheap-0.1.1-py3-none-any.whl

Download URL indexedheap-0.1.1-py3-none-any.whl
Size 9.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dac8c0be9006ec981a23c385e5f7f07470b510d87e206da4c70349ecc9aee171
BLAKE2b-256 checksum
How to use checksums
d429f2d20603e579d1e72430d9e1b1934c9d3e547bf225e90c7d9bde56e4d45d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.3

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page