In part 4 of MIT 6006 goes into heap data structures and heap sort. Heap sort runs in O(nlog n) time provided the array is already a heap and displays the heap invariant: that each parent node is greater than or equal to both its children. The additional step of creating a heap from an unordered array can be run in O(log n) time, which requires some careful analysis that the video goes into.
The heap creation step I found to be unintuitive on its face but eventually made sense to me. We don't care at all about the second half of the array because by definition these nodes will be leaves and display the heap invariant property by definition.
Traversing the tree is not difficult. Each left child will be at index 2n (counting from 1 - this is the reason for all the fenceposts scattered below) and the right child will be 2n+1
Here is how to create a max heap in python:
Once this piece of it is done the Heapsort algorithm is very simple. Take the head node into the output buffer and replace it with the tail node. To save space, the tail node can be swapped with the head node instead of using a separate output buffer, this allows the algorithm to run in place. Then, heapify the remainder of the tree. Repeat. Then you're done.
Here's the python implementation of that: