转自:http://www.mathcs.emory.edu/~cheung/Courses/171/Syllabus/9-BinTree/heap-delete.html
- Deleting a specific node from a Heap
- Problem description:
- You are given a heap.
For example:
- You are also given a index k
For example: k = 2
- Problem:
- Delete the value a[k] from the heap (so that the resulting tree is also a heap !!!)
- You are given a heap.
- Here is a Heap with the element a[2] = 5 deleted:
Heap before deleting the value a[2] = 5 Heap after the deletion... $64,000 question:
- How did you do it ???
- Problem description:
- The delete algorithm for a Heap
- The heap deletion algorithm in pseudo code:
1, Delete a node from the array (this creates a "hole" and the tree is no longer "complete") 2. Replace the deletion node with the "fartest right node" on the lowest level of the Binary Tree (This step makes the tree into a "complete binary tree") 3. Heapify (fix the heap): if ( value in replacement node < its parent node ) Filter the replacement node UP the binary tree else Filter the replacement node DOWN the binary tree
- Example:
- Delete the node containing the value 5 from the following heap:
After you delete the node, the tree is not a complete binary tree:
- Step 1: replace the deleted node with the node in the "fartest right location" of the lowest level
Result:
However, it is not a heap:
- We must fix the binary tree so that it becomes a heap again !!!
- Depending on the value of the replacement node, we must filter the replacement node upwards ordownwards
Since you have already seen the filter up algorithm --- in the heap insert algorithm --- I made the example to show you the filter down algorithm now
- We must fix the binary tree so that it becomes a heap again !!!
- Step 2: because the replacement node 21 is greater than its parent node (1), we must filter the replacement node down the tree
Filter the replacement node down the tree proceeds as follows:
- Compare the values of the replacement node with all its children nodes in the tree:
Some child node has a smaller value: the replacement node is not in its proper location
- Swap the replacement node with the smallest of the children nodes:
- After swapping:
Repeat !
- Compare the values of the replacement node (21) with all its children nodes in the tree:
Some child node has a smaller value: the replacement node is not in its proper location
- Swap the replacement node with the smallest of the children nodes:
After swapping:
Repeat !
- The replacement node (21) does not have any children node:
Done !!!
- Compare the values of the replacement node with all its children nodes in the tree:
- Delete the node containing the value 5 from the following heap:
- Warning:
- Sometimes, you have to filter the replacement node up the Binary tree !!!!!
Example:
- Delete the node with value = 33 from the following heap:
- Step 1: replace the deleted node with the "last" node in the lowest level (to make a complete binary tree)
Result:
- In this case, the replacement node must be filtered up into the binary tree:
Result:
- Conclusion:
if ( replacement node < its parent node ) filter the replacement node up the tree else filter the replacement node down the tree
- Heap deletion algorithm in Java:
public double remove( int k ) { int parent; double r; // Variable to hold deleted value r = a[k]; // Save return value a[k] = a[NNodes]; // Replace deleted node with the right most leaf // This fixes the "complete bin. tree" property NNodes--; // One less node in heap.... parent = k/2; /* ======================================================= Filter a[k] up or down depending on the result of: a[k] <==> a[k's parent] ======================================================= */ if ( k == 1 /* k is root */ || a[parent] < a[k] ) HeapFilterDown(k); // Move the node a[k] DOWN the tree else HeapFilterUp(k); // Move the node a[k] UP the tree return r; // Return deleted value... }
(We have already discussed the HeapFilterUp() algorithm .... )
- Filter Down algorithm in pseudo code:
HeapFilterDown( k ) // Filter node a[k] down to its proper place { while ( a[k] has at least 1 child node ) { child1 = 2*k; // left child of a[k] child2 = 2*k + 1; // right child of a[k] if ( a[k] has 2 childred nodes ) { if ( a[k] has smallest value among {a[k], a[child1], a[child2]} ) break; // a[k] in proper place, done else { /* ========================================= Replace a[k] with the smaller child node ========================================= */ if ( a[child1] < a[child2] ) { swap ( a[k], a[child1] ); k = child1; // Continue check.... } else { swap ( a[k], a[child2] ); k = child2; // Continue check... } } } else // a[k] must have only 1 child node { if ( a[k] has smallest value among {a[k], a[child1]} ) break; // a[k] in proper place, done else { swap ( a[k], a[child1] ); k = child1; // Continue check.... } } }
- The Filter down algorithm (describe above) is coded as a method:
/* ======================================================== HeapFilterDown(k): Filters the node a[k] down the heap ======================================================== */ void HeapFilterDown( int k ) { int child1, child2; // Indices of the children nodes of k double help; while ( 2*k <= NNodes ) // Does k have any child node ? { child1 = 2*k; // Child1 = left child of k child2 = 2*k+1; // Child2 = right child of k if ( child2 <= NNodes ) // If true, then k has 2 children nodes ! { /* ======================================== Node k has 2 children nodes.... Find the min. of 3 nodes !!! ======================================== */ if ( a[k] < a[child1] && a[k] < a[child2] ) { /* ------------------------------------------------------- Node k has the smallest value ! Node k is in correct location... It's a heap. Stop... ------------------------------------------------------- */ break; // STOP, it's a heap now } else { /* =================================================== Swap a[k] with the smaller of its 2 children nodes =================================================== */ if ( a[child1] < a[child2] ) { /* ------------------------------------------------------- Child1 is smaller: swap a[k] with a[child1] ------------------------------------------------------- */ help = a[k]; a[k] = a[child1]; a[child1] = help; k = child1; // Replacement node is a[child1] // in next iteration } else { /* ------------------------------------------------------- Child2 is smaller: swap a[k] with a[child2] ------------------------------------------------------- */ help = a[k]; a[k] = a[child2]; a[child2] = help; k = child2; // Replacement node is a[child2] // in next iteration } } } else { /* ======================================== Node k only has a left child node Find the min. of 2 nodes !!! ======================================== */ if ( a[k] < a[child1] ) { /* ------------------------------------------------------- Node k is in correct location... It's a heap. Stop... ------------------------------------------------------- */ break; } else { /* ------------------------------------------------------- Child1 is smaller: swap a[k] with a[child1] ------------------------------------------------------- */ help = a[k]; a[k] = a[child1]; a[child1] = help; k = child1; // Replacement node is a[child1] // in next iteration } } } }
- Example Program: (Demo above code)
How to run the program:
- Right click on link and save in a scratch directory
- To compile: javac testProg2.java
- To run: java testProg2
- The Heap class Prog file: click here
- The test Prog file: click here
- Right click on link and save in a scratch directory
- The heap deletion algorithm in pseudo code:
- Running time analysis of the heap delete algorithm
- Before we can perform a running time analysis, we must first understand how the algorithm works exactly...
- Summary of the heap delete algorithm:
- The deleted node is first replaced:
We will always have a complete binary tree:
- Then the HeapFilterUp() or the HeapFilterDown() algorithm will migrate the replacement node up or down into the binary tree:
and:
- The deleted node is first replaced:
- Fact:
- The number of times that the deleted node will migrate up or down into the binary tree is:
# migrations ≤ height of the binary tree
Example:
- The maximum number of times that replacement node can move down in a binary tree:
is at most 3 times:
The same argument can be apply to show that the maximum number of times that a nodes can move up the tree is at most the height of the tree.
- The number of times that the deleted node will migrate up or down into the binary tree is:
- Therefore:
Running time( delete(n) ) = Running time heap delete in heap with n node = height of a heap of n nodes
- Before we can perform a running time analysis, we must first understand how the algorithm works exactly...
- The height of a heap when it contains n nodes
- We have already determined this fact:
Let: n = # nodes in heap of height h 2h - 1 < n ≤ 2h+1 − 1 <===> 2h < n + 1 ≤ 2h+1 <===> h < lg(n + 1) ≤ h+1 ===> height of heap ~= lg(n + 1)
- We have already determined this fact:
- Running time of the heap delete algorithm
- Summary:
- Running time of delete into a heap of n nodes = height of the heap
- height of the heap containing n nodes ~= lg(n + 1)
- Running time of delete into a heap of n nodes = height of the heap
- Conclusion:
- Running time of delete into a heap of n nodes = O(lg(n))
- Summary: