javascript实现堆+堆排序

数据结构-堆

// 数据结构中的堆:一种特殊的二叉树,每一个子节点都不大于或不小于其父节点;
// 堆使用数组储存,节点在数组中的位置index 和它的父节点以及子节点的索引之间有一个映射关系。
// 第i个节点,其父节点的索引为 (i-1/2; 其左右子节点为 i*2+1 ,i*2+2 

// 大顶堆
// 创建堆
function buildMaxHeap(nums) {
    let len = nums.length;
    for(let i = Math.floor(len/2); i >= 0; i--) {
        shiftDown(nums, len, i);
    }
}


// 插入操作
// 每次插入都是将新数据放在数组最后
function insert(nums, data) {
    // 先插入
    nums.push(data);
    // 调整
    fixUp(nums, nums.length - 1);
}

// 上浮
// 如果一个节点比它的父节点大(最大堆)或者小(最小堆),那么需要将它同父节点交换位置
function shiftUp(nums, curIndex) {
    let parentIndex = Math.floor(curIndex/2);
    while(parentIndex >= 0) {
        if(nums[parentIndex] < nums[curIndex]) {
            swap(nums, parentIndex, curIndex);
            curIndex = parentIndex;
            parentIndex = Math.floor(curIndex/2)
        } else {
            break;
        }
    }
}


// 删除第一个元素
function remove(nums, len) {
    if(len < 2) return;
    swap(nums, 0, nums.length -1)
    shiftDown(nums, len-1, 0)
}


// 堆化
// 如果一个节点比它的父节点大(最大堆)或者小(最小堆),那么需要将它同父节点交换位置
function shiftDown(nums, len, curIndex) {
   let maxChildIndex = 2 * curIndex + 1;

   while(maxChildIndex < len) {
       // 拿到左右孩子最大的节点索引
       if(maxChildIndex + 1 < len && nums[maxChildIndex] < nums[maxChildIndex+1]) {
            maxChildIndex++;
       }
       if(nums[maxChildIndex] > nums[curIndex]) {
           swap(nums, curIndex, maxChildIndex);
           curIndex = maxChildIndex;
           maxChildIndex = 2 * curIndex + 1;
       }else {
           break;
       }
   }
}

function heapSort(nums) {
    // 构建大顶堆
    buildMaxHeap(nums);
    let len = nums.length;
    for(let i = len-1; i >= 0; i--) {
        swap(nums, 0, i);
        shiftDown(nums, i, 0);
    }
}


function swap(nums, index1, index2) {
    let temp = nums[index1];
    nums[index1] = nums[index2];
    nums[index2] = temp;
}

let arr1 = [10, 9, 8, 11, 12];
// buildMaxHeap(arr1);
heapSort(arr1);
console.log(arr1); // [ 8, 9, 10, 11, 12 ]


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值