数组实现的二叉树,一般实现完全二叉树,一般二叉树不建议使用,根节点下表从 【1】开始
性质
可由数组表示,位置k的节点的父节点位置为[k/2],而它的两个子节点的位置则分别为2k和2k+1
上浮
对一个元素进行上浮,直到到达顶部
function swim(k) {
while(k > 1 && less(parseInt(k / 2), k)) {
exch(parseInt(k / 2), k);
k = parseInt(k / 2);
}
}
下沉
// N 为数组长度
function sink(k) {
while(2 * k <= N) {
let j = 2 * k;
if (j < N && less(j, j + 1)) j++;
if(!less(k, j)) break;
exch(k, j);
k = j;
}
}
插入元素
在底部插入元素,并且上浮到合理位置
删除元素
1.将顶部元素与底部元素对换位置
2.pop()出尾部元素
3.下沉
实现
/*
* @Author : yangte
* @Date : 2020-10-10 23:51:41
* @LastEditTime : 2020-10-11 00:35:19
* @LastEditors : yangte
* @Description : 数据结构-堆
*/
class Heap {
constructor() {
this.pq = [null];
this.N = 0;
}
get isEmpty() {
return this.N === 0;
}
get size() {
return this.N;
}
insert(v) {
this.pq[++this.N] = v;
this._swim(this.N);
console.log(this.pq.join(',').slice(1));
}
delMax() {
this._exch(1, N--);
this.pq.pop();
this._sink(1);
}
_less(i, j) {
return this.pq[i] < this.pq[j];
}
_exch(i, j) {
[this.pq[i], this.pq[j]] = [this.pq[j], this.pq[i]];
}
// 上浮
_swim(k) {
while (k > 1) {
// 终止条件:子节点小于父节点
if (this._less(k, Math.floor(k / 2))) break;
this._exch(Math.floor(k / 2), k);
k = Math.floor(k / 2);
}
}
_sink(k) {
while (2 * k <= this.N) {
let j = 2 * k;
// 选择子节点:选择走哪条路,左或者右
if (j < this.N && this._less(j, j + 1)) {
j++;
}
// 终止条件:排序符合正常
if (this._less(j, k)) break;
this._exch(k, j);
k = j;
}
}
}