大顶堆生成、新增、删除、排序javascript实现

大顶堆小顶堆的概念和使用本文不赘述,使用js实现一个大顶堆的创建,新增,删除以及利用大顶堆排序

class Heap{
        constructor(data){
            // 存储data数据
            this.data = [...data];
            // 新增和删除不重新生成堆,根据二叉树快速的遍历新节点所在的树路径,需要源数据是已经初始化好的大顶堆结构
            this.isTopLargeHeap = false;
        }
        _swap(a, b){
            // 交换数据
            let tmp = this.data[a];
            this.data[a] = this.data[b];
            this.data[b] = tmp;
        }
        _heapDown(i, n){
            // i为当前父节点的下标,n为参与最大子节点的限制
            // 小顶堆只需修改下下方数值判断表达式 // 
            let data = this.data;
            // 父节点的值>左子节点的值
            if (2*i+1 < n && data[i] < data[2*i+1]) {
                this._swap(i,2*i+1);
                // 左子树遍历生成序列化
                this._heapDown(2*i+1, n);
            }
            // 父节点的值>右子节点的值
            if (2*i+2 < n && data[i] < data[2*i+2]) {
                this._swap(i,2*i+2);
                // 右子树遍历生成序列化
                this._heapDown(2*i+2, n);
            }
        }
        _heap(n){
            // n为限制当前最大参与序列化的值,主要为堆排序使用
            for (let i = Math.floor(n/2)-1; i >= 0; i--) {
                this._heapDown(i, n);
            }
        }
        createHeap(){
            // 创建当前数据的大顶堆
            this._heap(this.data.length);
            this.isTopLargeHeap = true;
            return this.data;
        }
        sort(){
            // 利用大顶堆升序排序,如是小顶堆可用来降序排序
            let i = this.data.length;
            while(i){
                this._heap(i);
                this._swap(0,i-1);
                i--;
            }
            this.isTopLargeHeap = false;
            return this.data;
        }
        getData(){
            return this.data;
        }
        insert(item){
            // 插入数据并保持大顶堆结构
            if (!this.isTopLargeHeap) throw 'please do createHeap first';
            this.data.push(item);
            let len = this.data.length,
                index = Math.floor(len/2)-1;
            while(index >= 0){
                console.log(index);
                this._heapDown(index, len);
                // 向上找父节点
                index = Math.floor((index+1)/2-1);
            }
        }
        delete(){
            if (!this.isTopLargeHeap) throw 'please do createHeap first';
            this.data[0] = this.data[this.data.length -1];
            this.data.splice(this.data.length -1,1);
            // 删除最顶部节点,此时把最后一个子节点放到根节点,只需处理根节点“下沉”
            this._heapDown(0, this.data.length);
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,915评论 1 32
  • 本文首发于我的个人博客:尾尾部落 排序算法是最经典的算法知识。因为其实现代码短,应该广,在面试中经常会问到排序算法...
    繁著阅读 10,050评论 3 118
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 28,514评论 1 45
  • 我们在介绍《什么是优先队列》的时候就注意到,如果每次都删除堆顶元素,那么将会得到一个有序的数据。因此,我们可以利用...
    编程小世界阅读 4,268评论 0 0
  • 说实在的我没有拿到《从原点出发》这本书,出于偶然亦或好奇就在网上阅读,虽然没有纸质图书那种真实亲切,其中蕴含的...
    你的世界我曾经来过阅读 4,657评论 0 0

友情链接更多精彩内容