1、堆内存和堆排序中的堆是一个意思吗?
不是,堆内存中的堆可以理解为一个仓库,是用于存放程序数据地方,堆排序中堆是一种数据结构,是存放数据的一种方式,是两个不同的概念。
2、堆排序中堆结构的样式是怎样的?
堆排序中堆是一个顺序排列的完全二叉树。树结构可以看成是一棵倒立的树,树根在上,树枝在下,树结构中存在一种特殊的树:满二叉树,满二叉树就是每个非叶子节点都有都有左子树和右子树,完全二叉树和满二叉树,主要区别在最后一层叶子节点,满二叉树是从左到右排列满的,使上一层的非叶子节点都有左右叶子节点,完全二叉树也是从左到右排列叶子节点,不过其不一定排列满了。满二叉树和完全二叉树都可以使用数组进行便利的存储。 顺序排列指的是堆这种数据结构分为两种:
- 大顶堆:父节点的数值不小于左子节点和右子节点
- 小顶堆:父节点的数值不大于左子节点和右子节点
3、什么是堆排序?
堆排序就是利用堆的数据结构设计的一种排序算法。堆排序是一种选择排序,不过正常的选择排序的时间复杂度是O(n²),堆排序采用二叉树的结构简化了比较的过程,利用堆的二叉树的结构快速的获取到最大值和最小值,其时间复杂度是O(nlogn)。
4、如何进行堆排序?
堆排序的中最重要的步骤就是:堆化, 堆排序的常用操作:删除,删除会取出根节点,将其和最后一个节点交换,这样会从上到下开始堆化。如果节点的数据比较小,则一直会“沉”到叶子节点,比较的次数为树的深度logn。堆排序的步骤:
- 将长度为n的无序数组进行堆化(从下到上进行堆化),相当于原来有一个堆,进行插入元素
- 取出二叉树的根节点,将其和树的最后的节点进行交换,对剩下n-1个元素进行堆化(从上到下开始堆化),相当于堆中删除顶上的元素
- 继续进行步骤2,将二叉树的根节点和树的最后的节点进行交换,对剩下n-2个元素进行堆化,直到只剩下一个元素。
5、大顶堆和小顶堆有什么特点?
堆是一种完全二叉树的结构,该结构可以方便的存储在数组中,根据数组的索引,可以得到:如果父节点的索引是i,则其左子树是2i+1,其右子树是2i+2,数组的长度为length,则其最后一个父节点的索引是length/2-1 - 大顶堆:父节点的数值不小于左子节点和右子节点,则R[i]>=R[2i+1] && R[i]>=R[2i+2],升序用大顶堆 - 小顶堆:父节点的数值不大于左子节点和右子节点,则R[i]<=R[2i+1] && R[i]<=R[2i+2],降序用小顶堆
6、java代码体现
public class HeapSort {
public static void main(String[] args) {
int[] arr = {1, 3, 9, 2, 4, 7, 6, 5, 8, 12, 10};
//将无序数组化为大顶堆, 最后一个根节点的索引是length/2-1,叶子节点不用进行堆化
for (int i = arr.length / 2 - 1; i >= 0; i--) {
// 堆化
heapAdjust(arr, i, arr.length);
}
for (int i = arr.length-1; i >=0; i--) {
// 交换根节点和最后一个节点
swapSeat(arr, 0, i);
// 堆化
heapAdjust(arr, 0 , i);
}
// 打印
printResult(arr);
}
private static void swapSeat(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b]=temp;
}
private static void printResult(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
private static void heapAdjust(int[] arr, int i, int length) {
// 取出要比较的元素
int temp = arr[i];
// 获取其子左节点
int children = 2 * i + 1;
while (children < length) {
// 比较左节点和右节点,如果右节点大于左节点,则选择替换右节点
if (children +1 < length && arr[children] < arr[children+1]) {
children++;
}
// 如果父节点比子节点大,则跳出
if (temp>=arr[children]) {
break;
}
arr[i]=arr[children];
i=children;
children= 2 * i + 1;
}
arr[i]=temp;
}
}
7、堆排序的特点
不稳定:相同的元素,排序后相对位置可能改变 原地排序:排序过程中不会申请多余的空间 开始建堆的时间复杂度是O(n),后面进行调整的时间复杂度是O(nlogn)
8、堆排序的类比总结
堆排序主要是利用堆这种数据结构(完全二叉树),来快速的得到数组中的最大值或者最小值,然后通过其进行排序的方法,类似于我有很多大小不一的弹珠,要将其进行从大到小的排序,堆结构相当于一个可以快速选出弹珠中最大或者最小的机器,我每次先将其放入机器,取出最大或者最小的弹珠,然后将剩下的弹珠放入机器,再取出最大或者最小的弹珠,直到剩下一个弹珠为止。