min heap, still need to reverse
This commit is contained in:
committed by
JamesFlare1212
parent
28243a596d
commit
83e54834d8
@@ -116,6 +116,10 @@ organized heap data, but incur a O(n log n) cost. Why?
|
|||||||
- The following is the sort algorithm with a main function to test it; the code makes a min heap.
|
- The following is the sort algorithm with a main function to test it; the code makes a min heap.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* The heapify function is designed to ensure that a subtree rooted at a given index i
|
/* The heapify function is designed to ensure that a subtree rooted at a given index i
|
||||||
* in an array representation of a min heap maintains the heap property.
|
* in an array representation of a min heap maintains the heap property.
|
||||||
*
|
*
|
||||||
@@ -160,14 +164,18 @@ std::vector<int> sortArray(std::vector<int>& nums) {
|
|||||||
heapify(nums, n, i);
|
heapify(nums, n, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now the first one is the largest, swap it to the back
|
// now the first one is the smallest, swap it to the back
|
||||||
// do this n-1 times.
|
// do this n-1 times.
|
||||||
for(int i=0; i<(n-1); i++){
|
for(int i=n-1; i>0; i--){
|
||||||
// build the min heap again, with 0 being the root.
|
// build the min heap again, with 0 being the root.
|
||||||
// but only consider n-1-i elements, as the others are already in the right place.
|
// but only consider i elements, as the others are already in the right place.
|
||||||
heapify(nums, n-1-i, 0);
|
std::swap(nums[0], nums[i]); // move smallest to the end
|
||||||
|
heapify(nums, i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reverse to get ascending order
|
||||||
|
std::reverse(nums.begin(), nums.end());
|
||||||
|
|
||||||
return nums;
|
return nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,10 +211,10 @@ The above program prints the following:
|
|||||||
$ g++ heap_sort.cpp
|
$ g++ heap_sort.cpp
|
||||||
$ ./a.out
|
$ ./a.out
|
||||||
Original array:
|
Original array:
|
||||||
42 12 13 65 98 45 97 85 76 90
|
42 12 13 65 98 45 97 85 76 90
|
||||||
|
|
||||||
Sorted array:
|
Sorted array:
|
||||||
12 42 13 65 90 45 97 85 76 98
|
12 13 42 45 65 76 85 90 97 98
|
||||||
```
|
```
|
||||||
|
|
||||||
## 24.9 Summary Notes about Vector-Based Priority Queues
|
## 24.9 Summary Notes about Vector-Based Priority Queues
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/* The heapify function is designed to ensure that a subtree rooted at a given index i
|
/* The heapify function is designed to ensure that a subtree rooted at a given index i
|
||||||
* in an array representation of a heap maintains the heap property.
|
* in an array representation of a min heap maintains the heap property.
|
||||||
* While the function doesn't have an explicit base case like some recursive functions,
|
* While the function doesn't have an explicit base case like some recursive functions,
|
||||||
* it inherently terminates due to the following conditions:
|
* it inherently terminates due to the following conditions:
|
||||||
*
|
*
|
||||||
@@ -11,19 +12,19 @@
|
|||||||
* In this scenario, the conditions left < n and right < n in the if statements evaluating the children will both be false,
|
* In this scenario, the conditions left < n and right < n in the if statements evaluating the children will both be false,
|
||||||
* preventing further recursive calls.
|
* preventing further recursive calls.
|
||||||
*
|
*
|
||||||
* Heap Property Satisfaction: If the node at index i is greater than or equal to its children (or if it has no children),
|
* Heap Property Satisfaction: If the node at index i is less than or equal to its children (or if it has no children),
|
||||||
* the heap property is already satisfied. Consequently, the variable largest remains equal to i,
|
* the heap property is already satisfied. Consequently, the variable smallest remains equal to i,
|
||||||
* and the condition largest != i evaluates to false.
|
* and the condition smallest != i evaluates to false.
|
||||||
* This prevents the swap operation and the subsequent recursive call, leading to termination.
|
* This prevents the swap operation and the subsequent recursive call, leading to termination.
|
||||||
* In essence, the function will return when:
|
* In essence, the function will return when:
|
||||||
* The node is a leaf node.
|
* The node is a leaf node.
|
||||||
* The node's value is greater than or equal to its children's values, maintaining the heap property.
|
* The node's value is less than or equal to its children's values, maintaining the heap property.
|
||||||
* These implicit conditions ensure that the recursion does not continue indefinitely.
|
* These implicit conditions ensure that the recursion does not continue indefinitely.
|
||||||
*
|
*
|
||||||
* Why Not Just Heapify Once? A single call to heapify on the entire array
|
* Why Not Just Heapify Once? A single call to heapify on the entire array
|
||||||
* wouldn't suffice because heapify is designed to correct violations of
|
* wouldn't suffice because heapify is designed to correct violations of
|
||||||
* the heap property starting from a specific node, assuming its subtrees are already heaps.
|
* the heap property starting from a specific node, assuming its subtrees are already heaps.
|
||||||
* Initially, the array doesn't have this structure, so multiple calls are necessary to build the initial max-heap.
|
* Initially, the array doesn't have this structure, so multiple calls are necessary to build the initial min-heap.
|
||||||
* Similarly, during the sorting phase, each extraction disrupts the heap structure, necessitating a call to heapify to restore order.
|
* Similarly, during the sorting phase, each extraction disrupts the heap structure, necessitating a call to heapify to restore order.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
@@ -40,8 +41,8 @@ void heapify(std::vector<int>& nums, int n, int i){
|
|||||||
smallest = right;
|
smallest = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
// after the above, smallest basically will either stay the same, or will be either left or right, depending on nums[left] is larger or nums[right] is larger. largest stays the same if it is already larger than its two children.
|
// after the above, smallest basically will either stay the same, or will be either left or right, depending on nums[left] is smaller or nums[right] is smaller. smallest stays the same if it is already smallest than its two children.
|
||||||
// if largest is changed, then we do need to swap.
|
// if smallest is changed, then we do need to swap.
|
||||||
if(smallest != i){
|
if(smallest != i){
|
||||||
std::swap(nums[i], nums[smallest]);
|
std::swap(nums[i], nums[smallest]);
|
||||||
heapify(nums, n, smallest);
|
heapify(nums, n, smallest);
|
||||||
@@ -58,20 +59,22 @@ std::vector<int> sortArray(std::vector<int>& nums) {
|
|||||||
// This bottom-up approach guarantees that each subtree satisfies the heap property before moving to the next node.
|
// This bottom-up approach guarantees that each subtree satisfies the heap property before moving to the next node.
|
||||||
for(int i=n/2-1; i>=0; i--){
|
for(int i=n/2-1; i>=0; i--){
|
||||||
// heapify the subtree whose root is at i
|
// heapify the subtree whose root is at i
|
||||||
// i.e., build a max heap, with i being the root; and this heap contains nodes from i to n-1;
|
// i.e., build a min heap, with i being the root; and this heap contains nodes from i to n-1;
|
||||||
heapify(nums, n, i);
|
heapify(nums, n, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now the first one is the largest, swap it to the back
|
// now the first one is the smallest, swap it to the back
|
||||||
// do this n-1 times.
|
// do this n-1 times.
|
||||||
for(int i=0; i<(n-1); i++){
|
for(int i=n-1; i>0; i--){
|
||||||
// nums[0] is always the largest one
|
// build the min heap again, with 0 being the root.
|
||||||
std::swap(nums[0], nums[n-1-i]);
|
// but only consider i elements, as the others are already in the right place.
|
||||||
// build the max heap again, with 0 being the root.
|
std::swap(nums[0], nums[i]); // move smallest to the end
|
||||||
// but only consider n-1-i elements, as the others are already in the right place.
|
heapify(nums, i, 0);
|
||||||
heapify(nums, n-1-i, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reverse to get ascending order
|
||||||
|
std::reverse(nums.begin(), nums.end());
|
||||||
|
|
||||||
return nums;
|
return nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user