js堆排序

**堆排序**
  堆排序可以理解为二叉树形式的排序,对于二叉树,根节点一定是最大值或者最小值,由此对数据进行堆排序每一轮可以确定一个最大值和最小值。在对剩下的树进行排序,只到最终剩下一个。结束
  针对堆排序(完全二叉树)需要知道以下几点:
    最后一个非叶子节点的下标为:数组长度/2-1;
    非叶子节点的左子节点为:当前下标*2+1;
    非叶子节点的右子节点为:当前下标*2+2;
    针对以上信息,便可以进行堆排序了。具体操作如下

let arr = [8,9,1,7,2,3,5,4,6,0];
                for(let i = 0;i<arr.length-2;i++){//判断只剩最后两个值时,不在进行堆排序直接跳出循环
                    let nonleafNode = Math.floor((arr.length-i)/2)-1;//最后一个非叶节点
                    for(let j = nonleafNode;j>=0;j--){
                        let leftChildNode = j*2+1;//当前节点的左子节点下标
                        let rightChildNode = j*2+2;//当前节点的右子节点下标
                        let max = "";//存储最大值
                        if(leftChildNode<(arr.length-i)&&arr[j]<arr[leftChildNode]){//当前非叶节点和左子节点比较,如果非叶节点<左子节点,替换
                            max = arr[leftChildNode];
                            arr[leftChildNode] = arr[j];
                            arr[j] = max;
                        }
                        if(rightChildNode<(arr.length-i)&&arr[j]<arr[rightChildNode]){//当前非叶节点和右子节点比较,如果非叶节点<右子节点,替换
                            max = arr[rightChildNode];
                            arr[rightChildNode] = arr[j];
                            arr[j] = max;
                        }
                    }
                    let arrMax = arr[0];
                    arr[0] = arr[arr.length-1-i];
                    arr[arr.length-1-i] = arrMax;
                }
                if(arr[0]>arr[1]){
                    let max = arr[0];
                    arr[0] = arr[1]
                    arr[1] = max;
                }

具体操作思路为:

  找到数组中最后一个非叶节点,然后从当前下标开始往前遍历每一个非叶节点,与他们的左右子节点进行比较,替换,保证当前节点比他的左右子节点都大。最终一次遍历后,第一个节点一定是值最大。然后将第一个值和最后一个值替换。

  数组减去最后一个值,再次进行上面的步骤,每次找到一个最大值放到当前数组(已经被减的数组)最后,然后再对此数组减去最后一个值,再进行上面的步骤。

  当数组只剩两个值的时候就不需要进行排序了,直接比较赋值就可以了。

  我的方法没有对数组进行减,只是在每次遍历的时候将应该减去的值进行了忽略,实际上和减去是一样的。

posted @ 2022-08-25 16:32  奔跑的哈密瓜  阅读(107)  评论(0编辑  收藏  举报