问题
I am refreshing on algorithm theory (from Cormen).
There is an exercise in the chapter for binary tries that asks:
Can the min-heap property be used to print out the keys of an n-node tree in sorted order in O(n) time? Show how, or explain why not.
I thought yes it is possible.
In the min heap the element in a node is smaller than both its children.
So the root of the heap is always the smaller element of all the n elements and the left child of the root is the smaller than all the elements in the left subtree and the right child of the root is the smaller than all the elements in the right subtree etc.
So if keep we exracting the root, print it and then update the root with the smaller of its children we keep the min-heap property and we print in sorted order. (I am thinking of a min heap that is not array based).
So this could be done in O(n) time since to update the root, we just compare the 2 children and update the root's pointer to be the smaller of the 2.
But I checked here in the solution:
Cormen Supplement Solutions
And 1)it talks about max-heaps 2) it says it can not be done in O(n) time:
In a heap, a node’s key is both of its children’s keys. In a binary search tree, a node’s key is its left child’s key, but its right child’s key. The heap property, unlike the binary-searth-tree property, doesn’t help print the nodes in sorted order because it doesn’t tell which subtree of a node contains the element to print before that node. In a heap, the largest element smaller than the node could be in either subtree. Note that if the heap property could be used to print the keys in sorted order in O(n) time, we would have an O(n)-time algorithm for sorting, because building the heap takes only O(n) time. But we know (Chapter 8) that a comparison sort must take (n lg n) time.
From my point of view I can understand that using a max-heap, it is not possible to print them in O(n).
But isn't it possible to do it using the min-heap property for the reasoning I explained?
Also why does the solution ignore the min-heap. Is it a typo or error?
Am I misundertanding something here?
回答1:
Firstly the omission of min-heaps in the discussion probably isn't a typo, it doesn't really matter if we're talking about a min heap or a max heap (the comparator is just reversed).
The problem with only extracting the root and then replacing with the smaller of its two children is that the left child is not guaranteed to be smaller than all the nodes in the right subtree (and vice verse). Consider the following heap
1
/ \
4 6
/\ /\
5 8 9 7
After printing 1
you have to reheapify which is to say you extract 1
and replace it with the last element in the last row, in this case 7
. You then switch for as long as you need to return the heap to it's correct state
take away root and last node to root
7
/ \
4 6
/\ /
5 8 9
swap
4
/ \
7 6
/\ /
5 8 9
swap
4
/ \
5 6
/\ /
7 8 9
all of that swapping costs you log n
time.
If you instead replaced the root node with 4
, you would still have to go through the left branch to reheapify the structure adding cost to the linear cost of extracting the root nodes. What if the heap looked like this
1
/ \
4 9
/\ /\
5 6 11 15
/\
8 7
The pages I looked at forming the solution
1) Wikipedia: binary heap
2) Wolfram MathWorld: heap The heaps here are especially helpful in understanding why it's not a linear operation.
回答2:
Consider an array representation of the min-heap. You have the minimum at the root. Extract the root and replace it with the last array element, i.e. with the last leaf in the lowest, incomplete "row" of leaves. Perform the MIN-HEAPIFY operation (obv. same as CLRS MAX-HEAPIFY, but with reversed comparison). This takes O(log n) and result is the second least element at the root. Repeat until the heap is empty. This gives a sorted sequence.
The complexity of the algorithm is therefore
log (n) + log (n-1) + log (n-2) + ... + 1 <= n*log n
i.e. O(n*log n)
which is to be expected or otherwise, we would have obtained a comparison based sort with complexity less than O(nlogn) and this is impossible.
回答3:
I guess what you are thinking is basically, that a heap (considering a min heap), has the smallest element as its root. Now for the second smallest element, both the left and right subtree have min heap property, so we can simply compare the left and right child to find the second smallest element. And same can be continued.... so its O(n) ? One thing that you are ignoring is that with each level the number of elements to be compared are also increasing... for the smallest - 0 comparison (root is the smallest) for the second smallest - 1 comparison (either root of left tree or root of right tree) lets say left tree root is smaller than right tree root node. for third smallest - 2 comparison. ( either root of right tree or either of two children of left subtree). You are ignoring this comparison part for your calculation of asymptotic time complexity.
来源:https://stackoverflow.com/questions/8110844/print-a-tree-in-sorted-order-using-heap-properties-cormen