# ECE 250: DSA ## Heaps A heap is a binary tree **stored in an array** in which all levels but the lowest are filled. It is guaranteed that the parent of index $i$ is greater than or equal to the element at index $i$. - the parent of index $i$ is stored at $i/2$ - the left child of index $i$ is stored at $2i$ - the right child of index $i$ is stored at $2i+1$ (Source: Wikimedia Commons) The **heapify** command takes a node and makes it and its children a valid heap. ```rust fn heapify(&mut A: Vec, i: usize) { if A[2*i] >= A[i] { A.swap(2*i, i); heapify(A, 2*i) } else if A[2*i + 1] >= A[i] { A.swap(2*i + 1, i); heapify(A, 2*i + 1) } } ``` Repeatedly heapifying an array from middle to beginning converts it to a heap. ```rust fn build_heap(A: Vec) { let n = A.len() for i in (n/2).floor()..0 { // this is technically not valid but it's much clearer heapify(A, i); } } ``` ### Heapsort Heapsort constructs a heap annd then does magic things that I really cannot be bothered to figure out right now. ```rust fn heapsort(A: Vec) { build_heap(A); let n = A.len(); for i in n..0 { A.swap(1, i); heapify(A, 1); // NOTE: heapify takes into account the changed value of n } } ``` ### Priority queues A priority queue is a heap with the property that it can remove the highest value in $O(\log n)$ time. ```rust fn pop(A: Vec, &n: usize) { let biggest = A[0]; A[0] = n; *n -= 1; heapify(A, 1); return biggest; } ``` ```rust fn insert(A: Vec, &n: usize, key: i32) { *n += 1; let i = n; while i > 1 && A[parent(i)] < key { A[i] = A[parent(i)]; i = parent(i); } A[i] = k; } ```