堆排序以及Java实现
Java数据结构与算法填坑
什么是堆?
首先堆是完全二叉树——深度为k,有n个节点,对树中的节点从上至下,从左至右的顺寻进行编号,若编号为i的节点与满二叉树中编号为i的节点在二叉树中的位置相同,就称为完全二叉树
堆的分类
堆分为:
1.大根堆:指每个父节点的值都比左右子节点的值大的完全二叉树
2.小根堆:指每个父节点的值都比左右子节点的值小的完全二叉树
堆排序的思想
以从小到大排序为例:
1)把待排序的数组构造成一个大根堆
2)把整个序列的最大值(目前这个堆的根节点)与末尾元素进行交换
3)去掉最后一个节点,剩余n-1个节点,递归执行
堆排序的实现
把数组变成堆
public static void adjustHeap(int[] arr, int i, int length) {
int temp = arr[i]; //取出当前元素的值,保存在临时的变量中
//1.j = i*2 + 1 ------> j是i节点的左子节点
for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
if (j + 1 < length && arr[j] < arr[j + 1]) {
//说明左子节点的值小于右子节点的值
j++; //指向右子节点
}
if (arr[j] > temp) {
//子节点大于父节点
arr[i] = arr[j]; //把较大的值赋给当前节点
i = j; //i指向j,循环比较
} else {
break;
}
}
//for循环结束后,我们已经把以i为父节点的树的最大值放在了最顶上
arr[i] = temp; //将temp值放在调整后的位置
System.out.println(Arrays.toString(arr));
}
堆排序
public static void heapSort(int[] arr) {
int temp = 0;
//1.将无序序列构建成一个堆
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
//2.将堆顶元素和末尾元素交换,将最大元素“沉”到数组末端
//3.重新调整结构,使其满足堆的定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序
for (int i = arr.length - 1; i >= 0; i--) {
temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
adjustHeap(arr, 0, i);
}
}
样例及运行结果
arr = {7,4,5,9,6}