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; }
具体操作思路为:
找到数组中最后一个非叶节点,然后从当前下标开始往前遍历每一个非叶节点,与他们的左右子节点进行比较,替换,保证当前节点比他的左右子节点都大。最终一次遍历后,第一个节点一定是值最大。然后将第一个值和最后一个值替换。
数组减去最后一个值,再次进行上面的步骤,每次找到一个最大值放到当前数组(已经被减的数组)最后,然后再对此数组减去最后一个值,再进行上面的步骤。
当数组只剩两个值的时候就不需要进行排序了,直接比较赋值就可以了。
我的方法没有对数组进行减,只是在每次遍历的时候将应该减去的值进行了忽略,实际上和减去是一样的。