(二叉)堆是一个数组。它可以看成一个近似的完全二叉树,树上的每一个节点对应数组中的一个元素。除了最底层外,该树是完全充满的,而且是从左向右填充。表示堆得数组A包括两个属性,A.length给出数组元素的个数,A.heapSize表示有多少个堆元素存储在该数组中。
最大堆:父节点的值大于等于子节点的值。
最小堆:父节点的值小于等于子节点的值。
MAX_HEAPIFY过程:时间复杂度是O(lgn),它是维护堆性质的关键。
BUILD-MAX_HEAP过程:线性时间复杂度,功能是从无序的输入数据数组中构造一个最大堆。
HEAP-SORT过程:时间复杂度是O(nlgn),功能是对一个数组进行原址排序。
MAX_HEAP_INSERT,HEAP-EXTRACT-MAX,HEAP-INCRESE_KEY,HEAP-MAXIMUM过程:时间复杂度O(lgn),功能是利用堆实现一个优先队列。
具体实现代码(最大堆):
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; a.sort(function(){return Math.random()>0.5}); a.heapSize = a.length; console.log(a.join('\t')); //buildMaxHeap(a); heapSort(a); console.log(a.join('\t')); function heapSort(a){ buildMaxHeap(a); for(var i = a.length-1; i>0;i--){ exchange(a, 0, i); a.heapSize--; maxHeapify(a, 0); } } function heapMaximum(a){ return a[0]; } function heapExtractMax(a){ if(a.heapSize<0){ throw(new Error('heap underflow')); } max = a[0]; a[0] = a[a.heapSize - 1]; a.heapSize--; maxHeapify(a, 0); return max; } function heapIncreaseKey(a, i, key){ if(key < a[i]){ throw(new Error('new key is smaller then current key')); } a[i] = key; var pi; while(i>0){ pi = parent(i); if(a[pi] < a[i]){ exchange(a, i, pi); i = pi; } else { break; } } } function maxHeapInsert(a, key){ a[a.heapSize] = -Infinity; a.heapSize++; heapIncreaseKey(a, a.heapSize - 1, key); } function buildMaxHeap(a){ for(var i = a.length>>1; i>=0;i--){ maxHeapify(a, i); } } function buildMaxHeap2(a){ a.heapSize = 1; for(var i = 1; i < a.length; i++){ maxHeapInsert(a, a[i]); } } function heapDelete(a, i){ a.heapSize--; a[i] = a[a.heapSize]; maxHeapify(a, i); a[a.heapSize] = null; } function maxHeapify(a, i){ var l = left(i); var r = right(i); var largest; if(l<a.heapSize && a[l]>a[i]){ largest = l; } else { largest = i; } if(r<a.heapSize && a[r]>a[largest]){ largest = r; } if(largest!=i){ exchange(a,i,largest); maxHeapify(a,largest); } } function exchange(a,i,largest){ var temp = a[i]; a[i] = a[largest]; a[largest] = temp; } function left(i){ return i<<1 | 0x1; } function right(i){ return (i<<1) + 2; } function parent(i){ return (i-1)>>1; } /*function left(i){ return i<<1; } function right(i){ return i<<1 | 0x1; } function parent(i){ return i>>1; }*/
最小堆实现代码:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; a.sort(function(){return Math.random()>0.5}); a.heapSize = a.length; console.log(a.join('\t')); //buildMaxHeap(a); //heapSort(a); console.log(a.join('\t')); function heapSort(a){ buildMinHeap(a); for(var i = a.length-1; i>0;i--){ exchange(a, 0, i); a.heapSize--; minHeapify(a, 0); } } function heapMinimum(a){ return a[0]; } function heapExtractMin(a){ if(a.heapSize<0){ throw(new Error('heap underflow')); } min = a[0]; a[0] = a[a.heapSize - 1]; a.heapSize--; minHeapify(a, 0); return min; } function heapIncreaseKey(a, i, key){ if(key > a[i]){ throw(new Error('new key is bigger then current key')); } a[i] = key; var pi; while(i>0){ pi = parent(i); if(a[pi] > a[i]){ exchange(a, i, pi); i = pi; } else { break; } } } function minHeapInsert(a, key){ a[a.heapSize] = Infinity; a.heapSize++; heapIncreaseKey(a, a.heapSize - 1, key); } function buildMinHeap(a){ for(var i = a.length>>1; i>=0;i--){ minHeapify(a, i); } } function buildMinHeap2(a){ a.heapSize = 1; for(var i = 1; i < a.length; i++){ minHeapInsert(a, a[i]); } } function heapDelete(a, i){ a.heapSize--; a[i] = a[a.heapSize]; minHeapify(a, i); a[a.heapSize] = null; } function minHeapify(a, i){ var l = left(i); var r = right(i); var least; if(l<a.heapSize && a[l]<a[i]){ least = l; } else { least = i; } if(r<a.heapSize && a[r]<a[least]){ least = r; } if(least!=i){ exchange(a,i,least); minHeapify(a,least); } } function exchange(a,i,least){ var temp = a[i]; a[i] = a[least]; a[least] = temp; } function left(i){ return i<<1 | 0x1; } function right(i){ return (i<<1) + 2; } function parent(i){ return (i-1)>>1; } /*function left(i){ return i<<1; } function right(i){ return i<<1 | 0x1; } function parent(i){ return i>>1; }*/
https://github.com/hanyeah/lianxi/tree/master/算法导论/6
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。