1. package lhz.algorithm.chapter.six; 
  2. /** 
  3.  * HEAP-DELETE,《算法导论》习题6.5-7 
  4.  * 习题原文: 
  5.  * The operation HEAP-DELETE(A, i) deletes the item in node i from heap A. Give an 
  6.  * implementation of HEAP-DELETE that runs in O(lg n) time for an n-element max-heap. 
  7. * 本文地址:http://mushiqianmeng.blog.51cto.com/3970029/745621
  8.  * @author lihzh(苦逼coder) 
  9.  */ 
  10. public class HeapDelete { 
  11.      
  12.     //初始化MaxHeap堆 
  13.     private static int[] heap = new int[] {1171065914328}; 
  14.     //初始化堆大小 
  15.     private static int heapSize = heap.length; 
  16.  
  17.     public static void main(String[] args) { 
  18.         //简单测试代码 
  19.         heapDelete(9); 
  20.         printHeap(); 
  21.         heapDelete(3); 
  22.         printHeap(); 
  23.         heapDelete(6); 
  24.         printHeap(); 
  25.         heapDelete(3); 
  26.         printHeap(); 
  27.         heapDelete(5); 
  28.         printHeap(); 
  29.         heapDelete(3); 
  30.         printHeap(); 
  31.         heapDelete(1); 
  32.         printHeap(); 
  33.     } 
  34.      
  35.     /** 
  36.      * 删除堆中指定元素,利用<code>MaxHeapify</code>算法(复杂度:O(lgn)) 
  37.      * 复杂度分析: 
  38.      * 当删除的索引等于1或者交换过来的元素小于其父元素的时候,调用MaxHeapify 
  39.      * 算法,重新构造堆,此时复杂度为:O(lgn) 
  40.      * 当大于父元素的时候,递归交换其与父元素的位置,此时复杂度仍为:O(lgn) 
  41.      * 综上,复杂度为:O(lgn) 
  42.      * @param heapIndex 堆中元素索引(1-heapSize) 
  43.      */ 
  44.     private static void heapDelete(int heapIndex) { 
  45.         if (heapIndex > heapSize) { 
  46.             System.err.println("索引超过堆中最大元素个数,元素不在堆中!"); 
  47.             return
  48.         } 
  49.         //数组索引比堆索引小1 
  50.         int arrayIndex = heapIndex - 1
  51.         int key = heap[arrayIndex];  
  52.         heap[arrayIndex] =  heap[heapSize-1]; 
  53.         heap[heapSize-1] = key; 
  54.         heapSize--; 
  55.         if (heapIndex > 1) { 
  56.             int parentIndex = heapIndex / 2
  57.             if (heap[arrayIndex] > heap[parentIndex-1]) { 
  58.                 while (parentIndex > 1 
  59.                         && heap[arrayIndex] > heap[parentIndex-1]) { 
  60.                     int temp = heap[arrayIndex]; 
  61.                     heap[arrayIndex] = heap[parentIndex-1]; 
  62.                     heap[parentIndex-1] = temp; 
  63.                     arrayIndex = parentIndex - 1
  64.                     parentIndex = parentIndex / 2
  65.                 } 
  66.             } 
  67.         } else { 
  68.             maxHeapify(heapIndex); 
  69.         } 
  70.     } 
  71.      
  72.     /** 
  73.      * 之前实现的<code>MaxHeapify</code>算法 
  74.      * @param array 
  75.      * @param index 
  76.      */ 
  77.     private static void maxHeapify(int index) { 
  78.         int l = index * 2
  79.         int r = l + 1
  80.         int largest; 
  81.         //如果左叶子节点索引小于堆大小,比较当前值和左叶子节点的值,取值大的索引值 
  82.         if (l <= heapSize && heap[l-1] > heap[index-1]) { 
  83.             largest = l; 
  84.         } else { 
  85.             largest = index; 
  86.         } 
  87.         //如果右叶子节点索引小于堆大小,比较右叶子节点和之前比较得出的较大值,取大的索引值 
  88.         if (r <= heapSize && heap[r-1] > heap[largest-1]) { 
  89.             largest = r; 
  90.         } 
  91.         //交换位置,并继续递归调用该方法调整位置。 
  92.         if (largest != index) { 
  93.             int temp = heap[index-1]; 
  94.             heap[index-1] = heap[largest-1]; 
  95.             heap[largest-1] = temp; 
  96.             maxHeapify(largest); 
  97.         } 
  98.     } 
  99.      
  100.     private static void printHeap() { 
  101.         for (int i = 0; i < heapSize; i++) { 
  102.             System.out.print(heap[i] + " "); 
  103.         } 
  104.         System.out.println(); 
  105.     } 
  106.      
  107.