大顶堆小顶堆的概念和使用本文不赘述,使用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);
}
}
网友评论