堆:
是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序:
是指利用堆这种数据结构所设计的一种排序算法
- heapInsert(arr,index) 增大堆结构
先建立大根堆,这是一个往上走的过程,进来的元素与父元素比,大了就往上走,此时数组仍为无序数组 - 最大的在根位置上,将最大的和最后那个小的做交换,此时最大的这个在根中失效,从堆中出来,长度-1
- heapify(arr,index,heapSize) 缩小堆结构
重新调整大根堆,小的此时在0位置上,这是一个往下沉的过程,它要跟两个孩子比,所以要先找到孩子里大的,再跟这个大的作比较,小了就往下走小的此时在0位置上,重新调整大根堆,这是一个往下沉的过程,它要跟两个孩子比,所以要先找到孩子里大的,再跟这个大的作比较,小了就往下走 - 不断将大的拿出,得到有序数组
//时间复杂度是O(nlogn)
var arr = [8,6,4,7,1];
function heapSort(arr){
if(arr == null || arr.length < 2){
return;
}
//1.先建立大根堆
for(var i=0; i<arr.length; i++){
heapInsert(arr,i);
}
var heapSize = arr.length;
//2.0位置上的和最后一个做交换,最后一个出来,也就是最大的那个,长度-1
swap(arr,0,--heapSize);
while(heapSize > 0){
//3.原先在最后的调到0位置了,重新调整大根堆,再继续做交换,直到长度为0,排好序
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}
function heapInsert(arr,index){
while(arr[index]>arr[(index-1)/2]){
swap(arr,index,(index-1)/2);
index = (index-1)/2;
}
}
function heapify(arr,index,heapSize){
var left = index * 2 + 1;
while(left < heapSize){
var largest = left + 1 < heapSize && arr[left + 1] > arr[left]
? left + 1
: left;
largest = arr[largest] > arr[index] ? largest : index;
if(largest == index){
break;
}
swap(arr,largest,index);
index = largest;
left = index * 2 + 1;
}
}
function swap(arr,i,j){
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
heapSort(arr);
console.log(arr);
调试结果: