1.开篇介绍
2.时间空间复杂度
3.动态规划
4.贪心
5.二分查找
6.深度优先&广度优先
7.双指针
8.滑动窗口
9.位运算
10.递归&分治
11剪枝&回溯
12.堆
13.单调栈
14.排序算法
15.链表
16.set&map
17.栈
18.队列
19.数组
20.字符串
21.树
22.字典树
23.并查集
24.其他类型题
满二叉树:除叶子节点外,所有的节点都有两个子节点,这类二叉树称作满二叉树(Full Binarry Tree),如下图:
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层从右向左连续缺若干结点,这就是完全二叉树。
堆是一个完全二叉树,所以我们可以采用数组实现,不会浪费太多空间,堆中的每个节点的值总是不大于或不小于其父节点的值,堆分为大顶堆和小顶堆,大顶堆堆顶是元素中最大的一个,小顶堆堆顶是最小的,在向堆中加入元素的时候,能动态调整堆内元素的顺序,始终保持堆的性质。
parentIndex = [(index - 1) / 2]
,左节点索引leftIndex = index * 2 + 1
,右节点索引 rightIndex = index * 2 + 2
[size / 2]
O(logn)
动画过大,点击查看
O(logn)
动画过大,点击查看
class Heap { constructor(comparator = (a, b) => a - b, data = []) { this.data = data; this.comparator = comparator;//比较器 this.heapify();//堆化 } heapify() { if (this.size() < 2) return; for (let i = Math.floor(this.size()/2)-1; i >= 0; i--) { this.bubbleDown(i);//bubbleDown操作 } } peek() { if (this.size() === 0) return null; return this.data[0];//查看堆顶 } offer(value) { this.data.push(value);//加入数组 this.bubbleUp(this.size() - 1);//调整加入的元素在小顶堆中的位置 } poll() { if (this.size() === 0) { return null; } const result = this.data[0]; const last = this.data.pop(); if (this.size() !== 0) { this.data[0] = last;//交换第一个元素和最后一个元素 this.bubbleDown(0);//bubbleDown操作 } return result; } bubbleUp(index) { while (index > 0) { const parentIndex = (index - 1) >> 1;//父节点的位置 //如果当前元素比父节点的元素小,就交换当前节点和父节点的位置 if (this.comparator(this.data[index], this.data[parentIndex]) < 0) { this.swap(index, parentIndex);//交换自己和父节点的位置 index = parentIndex;//不断向上取父节点进行比较 } else { break;//如果当前元素比父节点的元素大,不需要处理 } } } bubbleDown(index) { const lastIndex = this.size() - 1;//最后一个节点的位置 while (true) { const leftIndex = index * 2 + 1;//左节点的位置 const rightIndex = index * 2 + 2;//右节点的位置 let findIndex = index;//bubbleDown节点的位置 //找出左右节点中value小的节点 if ( leftIndex <= lastIndex && this.comparator(this.data[leftIndex], this.data[findIndex]) < 0 ) { findIndex = leftIndex; } if ( rightIndex <= lastIndex && this.comparator(this.data[rightIndex], this.data[findIndex]) < 0 ) { findIndex = rightIndex; } if (index !== findIndex) { this.swap(index, findIndex);//交换当前元素和左右节点中value小的 index = findIndex; } else { break; } } } swap(index1, index2) {//交换堆中两个元素的位置 [this.data[index1], this.data[index2]] = [this.data[index2], this.data[index1]]; } size() { return this.data.length; } }