二叉堆操作

<!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>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值