(二叉 )堆:一个类似完全二叉树的数据结构
左孩子:2i
右孩子:2i+1
父节点:i/2
(以上结论如果记不住,用到时可以自己画个图推一下)
物理存储:用数组存储A(1,2,3....,n)
1.调整每个节点的算法:
如果要建立大顶堆,则需遵循每个父亲结点的值都要大于左右孩子的值
递归版本:
/**
*
* @param numbers
* 待调整数组
* @param i
* 待调整节点
* @param len堆的大小
*/
public static void maxHeapify(int[] numbers, int i, int len) {
int l = 2 * i + 1;
int r = 2 * i + 2;
int largest = i;
if (l < len && numbers[i] < numbers[l]) {
largest = l;
}
if (r < len && numbers[largest] < numbers[r]) {
largest = r;
}
if (largest != i) {
int temp = numbers[i];
numbers[i] = numbers[largest];
numbers[largest] = temp;
maxHeapify(numbers, largest, len);
}
}
非递归版本:
public static void maxHeapify1(int[] numbers, int i, int len) {
int l = 2 * i + 1;//下标从0开始时左孩子的下标
int r = 2 * i + 2;//下标从0开始时右孩子的下标
int largest = i;
if (l < len && numbers[i] < numbers[l]) {
largest = l;
}
if (r < len && numbers[largest] < numbers[r]) {
largest = r;
}
//修改递归调用
while (largest != i) {
int temp = numbers[i];
numbers[i] = numbers[largest];
numbers[largest] = temp;
i=largest;
l=2*i+1;
r=2*i+2;
if (l < len && numbers[i] < numbers[l]) {
largest = l;
}
if (r < len && numbers[largest] < numbers[r]) {
largest = r;
}
}
}
2.建立堆的算法:
自底向上建立,调整每个非叶子节点,叶子节点无需再调整
利用结论,完全二叉树中(n/2+1,...,n)为叶子节点
public static void buildMaxHeap(int[] numbers) {
int heapsize = numbers.length;
for (int i = heapsize / 2 - 1; i >= 0; --i) {
maxHeapify(numbers, i,heapsize);
}
}
3.堆排序的算法:
建立一个大顶堆,第一个元素与最后一个元素交换
缩小堆的规模,此时只有第一个节点可能不符合堆的性质,对第一个节点调用调整节点的算法
重复1,2步骤直到堆的规模缩小为1
// 堆排序算法,按从小到大排的
// 初始建立一个大顶堆,因为数组中的最大元素总在根节点A[0]中,通过把它与A[n]进行互换,可以把它放在正确的位置
// 这时从数组中去除第n个节点,这时只有根节点可能是违背最大堆的性质,这时调用一次堆调整方法就可以了,此时堆的规模减少了1
public static void heapSort(int[] numbers) {
int len = numbers.length;
buildMaxHeap(numbers);
for (int i = len; i >= 1; --i) {
int temp = numbers[i - 1];
numbers[i - 1] = numbers[0];
numbers[0] = temp;
maxHeapify(numbers, 0, i - 1);// 调用堆调整算法
}
}
4.优先队列:(最大优先队列、最小优先队列)
优先队列是一种用来维护由一组元素构成的集合S的数据结构,其中每个元素都有一个相关的值,称为关键字。一个最大优先队列支持一下操作:
insert(S,x):插入一个元素
maxNum(S):返回集合中最大的元素
extract-max(s):返回并从集合中删除最大的元素
increase-key(s,x,k):将元素x的关键字增加到k
应用:计算机系统的作业调度(上os时有个优先级调度算法)
完整代码:
https://github.com/tianqingwa/HeapSort