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

2019-07-13  本文已影响0人  hait_632c

大顶堆小顶堆的概念和使用本文不赘述,使用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);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读