【概念】
堆是一棵顺序存储的完全二叉树。
堆排序分为两种:
1)大根堆:所有的叶子不大于根。Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)
2)小根堆:所有的叶子不小于根。Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)
其中i=1,2,…,n/2向下取整;
当前节点为R[i],左孩子是R[2*i+1],右孩子是R[2*i+2]。父结点是R[(i-1)/2]。
【思想】
(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。
(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。
【例子】以建立大根堆为例
建立了堆之后,每次都是从数组的len/2的位置开始,比较下标为[len/2-1]的结点和他的孩子之间的关系,找到最大的,交换到根结点的位置,然后依次向前推一个。
1,3,4,5,2,6,9,7,8,0有10个数,10/2=5,那么从下标为[4]的结点开始比较,R[2]=2,比较2和和她的孩子0,根结点已经是最大了,不操作。
比较R[3]=5和她的孩子7、8,发现5比8小,互换。
比较R[2]=4和她的孩子6、9,发现9比4大,互换。再向前推一个。
比较R[1]=3和她的孩子8、2,发现8比3大,互换。3和下面的孩子7、5比较,交换7和3,此时得到大根堆。
比较R[0]=1和她的孩子8、9,发现9比1大,互换。
此时二叉树中根=9是根堆。
![](https://i-blog.csdnimg.cn/blog_migrate/6a1083ff66911d4cf900ade8dc75c9ec.png)
<!DOCTYPE html>
<html>
<head>
<title>Heap Sort</title>
<meta charset="utf-8"/>
<script type="text/javascript">
function heapSort(array){
console.time("time");
if(Object.prototype.toString.call(array).slice(8,-1)==='Array'){
var heapSize = array.length,temp;//建立堆
for(var i =Math.floor(heapSize /2)-1; i>=0; i--){
heapify(array,i,heapSize);
}
for(var j=heapSize-1;j>=1;j--){
temp = array[0];
array[0]=array[j];
array[j]=temp;
heapify(array,0,--heapSize);
}
console.timeEnd("use time");
return array;
}else{
return 'array is not an Array!';
}
}
function heapify(arr,x,len){
if(Object.prototype.toString.call(arr).slice(8,-1)==='Array'&&typeof x === 'number'){
var l=1*x+1,
r=2*x+2,
largest = x,
temp;
if(l<len && arr[l] > arr[largest]){
largest =l;
}
if(r<len && arr[r]> arr[largest]){
largest =r;
}
if(largest!=x){
temp = arr[x];
arr[x]=arr[largest];
arr[largest]=temp;
heapify(arr,largest,len);
}
}else{
return 'arr is not an Array or x is not a number'
}
}
var arr=[91,60,96,13,35];
document.write(heapSort(arr));
</script>
</head>
<body>
</body>
</html>