堆
作者:互联网
- 堆结构是用数组实现的完全二叉树结构
- 完全二叉树 中 如果 每颗子树的最大值在顶部, 就是大根堆
- 完全二叉树 中 如果 每颗子树的最小值在顶部, 就是小根堆
- 堆结构有俩个操作:heapInsert 和 heapify
- 优先级队列结构就是 堆结构
size
i 左节点:2 * i + 1
右节点:2 * i + 2
父节点:(i-1)/ 2
维护heapsize(堆大小)
当插入一个元素,初始位置就是 当前heaspsize的位置,然后和自己的父节点比较。如果比自己的父节点大,就交换,直到根节点。如果不大,就停止。这个操作就是heapInsert
public static void heapInsert(int[] arr, int index) {
//当前值小于其父节点就停止
// 当index为0. index-1/2 也为0.也停止了。
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, ((index -1 ) /2));
//交换之后,更新index
index = (index - 1) /2;
}
}
当取走0位置上的数之后(获取最大值), 调整堆的结构保持 是大根堆。
最后一个数和0 交换,然后调整。调整之后,最后一个数就不在堆里了。断掉
自己的左孩子 和 右孩子 PK,挑一个最大的。 和 自己再pk.
停的条件:左右孩子都没自己大,没有左右孩子了。
public static void heapify(int[] arr, int index, int size) {
int left = 2 * index + 1; // 左孩子下标
while (left < size) { // 有左孩子,
// 获取 左孩子和右孩子 值大 的 index
int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
// 孩子最大 和 自己比。
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) {
// 如果自己就是最大的,退出
break;
}
// 孩子比自己大,交换
swap(arr, largest, index);
// 更新index,继续往下
index = largest;
// 更新 左孩子 下标
left = 2 * index + 1;
}
}
排序
public void userSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int heapSize = arr.length;
// 插入堆,只是个大根堆,还未排序
for (int i = 0; i < arr.length; i++) {
heapInsert(arr, i);
}
// 开始调整,当前最大值在0,依次和最后的位置交换,就依次排好了。
swap(arr, 0, --heapSize);
while (heapSize > 0) {
heapify(arr, 0, heapSize);
swap(arr, 0, --heapSize);
}
}
标签:,index,arr,int,largest,节点,left 来源: https://www.cnblogs.com/clllll/p/16212639.html