<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
function MaxHeap(arr){
this.data=[];
if(Array.isArray(arr)){
this.data=arr;
//合并新数组后 在根据最后一个节点 进行节点的父节点排序 下沉
for(var i=this.getParent(this.data.length-1);i >= 0;i --){
this.siftDown(i);//
}
}
}
MaxHeap.prototype={
getSize:function(){
return this.data.length;
},
isEmpty:function(){
return this.data.length===0;
},
getData:function(){
return this.data;
},
findMax:function(){
if(this.isEmpty()){
throw new Error("数组为空!");
return null;
}
return this.data[0];
},
//根据index索引获取父结点
getParent:function(index){
if(index===0){
console.log("索引不能为0")
return null;
}
//一定要向上取整
return Math.floor((index-1)/2);
},
//根据索引 获取左节点
getLeftChild:function(index){
return index*2+1;
},
//根据索引 获取右节点
getRightChild:function(index){
return index*2+2;
},
//添加元素
add:function(item){
this.data.push(item);
this.siftUp(this.data.length-1);
},
//取出堆中最大元素
extractMax:function(){
var tempMax=this.findMax();
this.swap(0,this.data.length-1);
this.data.pop();
this.siftDown(0);
return tempMax;
},
//比对父节点的值是否小于新插入的值
siftUp:function(index){
//查看数组中的新插入的元素节点 是否大于目前的父节点
while(index > 0 && this.data[this.getParent(index)]<this.data[index]){
var parent = this.getParent(index);
//如果大于的情况下 位置调整 后继续比对再上一次节点元素
this.swap(index,parent);
index=parent;
}
},
//比对父节点的值是否小于新插入的值
siftDown:function(index){
var size = this.data.length;
while(this.getLeftChild(index)<size){
//获取index的左节点值
var j = this.getLeftChild(index);
//j+1 代表右节点
//首先判断j+1也就是右节点的下标是否超出范围
//然后再判断右节点是否大于左节点
//如果大于的情况 就设置J为右节点
if(j+1<size && this.data[j+1]>this.data[j])
j = this.getRightChild(index);
//上面判断了左右节点那个最大
//然后再比较index值和J的值 的大小
//如果index的值比现在的节点大 那就退出循环不然就替换元素
if(this.data[index] >= this.data[j])break;
//如果index的值小于J节点的值 那就替换
this.swap(index,j);
//然后赋值 继续下沉
index = j;
}
},
//交换值
swap:function(i,j){
var size=this.data.length;
if(i<0 || i>=size || i<0 || j>=size){
throw new Error("数据索引不正确!");
return false;
}
var temp = this.data[i];
this.data[i]=this.data[j];
this.data[j]=temp;
return true;
},
}
var heap=new MaxHeap(),
length=1000000;
console.time("普通堆排序,共花费了");
for(var i=0;i<length;i++){
heap.add(Math.ceil(Math.random()*100));
}
var sortData = [];
for(var i=0;i<length;i++){
sortData[i]=heap.extractMax();
}
for(var i=0;i<length;i++){
if(sortData[i-1]<sortData[i])
throw new Error("排序失败!")
}
console.log("排序成功!");
console.timeEnd("普通堆排序,共花费了")
//集合插入
console.time("集合插入堆排序,共花费了");
var heap1,
data1=[];
for(var i=0;i<length;i++){
data1.push(Math.ceil(Math.random()*100));
}
heap1 = new MaxHeap(data1);
var temp1=[];
for(var i=0;i<length;i++){
temp1[i]=heap1.extractMax();
}
for(var i=0;i<temp1.length;i++){
if(temp1[i-1]<temp1[i])
throw new Error("排序失败!")
}
console.log("排序成功!");
console.timeEnd("集合插入堆排序,共花费了")
</script>
</head>
<body>
</body>
</html>