堆排序
最大堆和最小堆广泛用于各种场景,JAVA中的PriorityQueue,操作系统的线程调度(看资料有人说,自己没研究),以及HBase中各种Scanner都是以堆的形式。最大堆是指根节点是整个集合中的最大值,最小堆是指根节点是整个集合中的最小值,这里以PriorityQueue的源码为例了解堆。
增加一个节点:(从下往上找)
为新增加的节点也就是最后的节点找位置
private final void upHeap() {
int i = size; //堆大小
Tnode = heap[i]; //最后插入的节点 // save bottom node
int j = i >>> 1;//插入节点的父节点位置
while (j > 0 && lessThan(node, heap[j])) {//从父节点开始向上一次查找,如果父节点小于刚插入的node
heap[i] = heap[j];//就把子节点的值赋值给父节点 // shift parents down
i = j;// j的值赋值给i
j = j >>> 1;//j继续找j的父节点位置
}
heap[i] = node; // install saved node
}
删除一个节点(从上往下找)
堆删除节点的方法,其实和给最后一个节点node找位置,从根节点开始找自己最小的子节点与node比较如果小于node,则把该节点的值赋值给父节点
private final void downHeap() {
int i = 1;//根节点位置
Tnode = heap[i]; //根节点的node值 // save top node
int j = i << 1;//子节点的位置 // find smaller child
int k = j + 1;//另一个子节点的位置
if (k <= size && lessThan(heap[k], heap[j])) {//找到比较小的子节点位置
j = k;
}
while (j <= size && lessThan(heap[j], node)) {//如果j<=size并且heap[j]小于node的值
heap[i] = heap[j];//赋值给父节点 // shift up child
i = j;//j的值赋值为i
j = i << 1;//找到j的子节点位置
k = j + 1;//找到j的另一个子节点位置
if (k <= size && lessThan(heap[k], heap[j])) {//找到较小的子节点
j= k;
}
}
heap[i] = node; //node安放在i的位置 // install saved node
}
}
堆排序就是先建立一个最大堆,然后把根节点跟最后的节点交换位置,然后把前n-1个集合数重新组合成最大堆,重复以上操作直到只剩一个节点。