一、大顶堆
二、小顶堆
三、堆排序
首先我讲一下大顶堆和小顶堆的基本概念大家先理解一下
所谓大顶堆通俗意义上来讲就是大的数放顶上,小的数放下面、也就是降序。所以需要保证每一个父节点都大于他的两个子节点。
小顶堆那肯定就是和大顶堆相反了,小的数放上面,大的数放下面,也就是升序、所以需要保证每一个父节点都小于他的两个子节点。
为了方便大家理解,我下面放上两个图。不然太抽象了。
当我们进行堆排序的时候我们就需要建立一个大顶堆或者小顶堆比如说我举一个例子
加入一个数组array[]{4,6,8,5,9}
我们需要将数组升序排列,也就是从小到大排列。一般升序排列我们用大顶堆,降序排列就反之用小顶堆。
所以我们第一件事情就是将数组构建成一个大顶堆。
这里呢我简单介绍一下怎么调整成一个大顶堆。
我们一般呢是先从最末有子节点的开始排。
首先呢我们先拿6开始做交换。让6和3结点和4结点的值进行比较再让3结点和4结点进行比较。那么我们可以知道4结点的9相对大一些,所以我们让6和9做一个交换。得到以下二叉树。
然后我们找0号位结点存的是4我们拿4,9,8三个结点进行上述比较我们发现9较大。我们把9跟4进行交换。得到以下二叉树
最后就是重复上面两个步骤直到得到大顶堆。
我们了解了过程之后,下面我上代码
public static void adjustHeap(int[] array, int i, int length) {
int temp = array[i];
for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
if (k+1<length && array[k] < array[k + 1]) {
k++;
}
if (array[k] > temp) {//让较大的那个值和结点进行比较
array[i] = array[k];//将较大的值赋给结点
i = k;//i = k 进入继续循环
} else {
break;//如果结点就是较大的值那么不做改变直接结束
}
}
array[i] = temp;//最后将temp里面保存的值赋给array[i]
}
这是将一个数组经过不停交换得到一个大顶堆。小顶堆则反之。
接下来开始排序。那么堆排序是怎么排序的呢???
其实是将堆顶元素和和末尾元素进行交换
例如现在的数组是{9,6,8,5,4}
我们就需要将9与4进行交换然后9固定得到数组{4,6,8,5}
然后再固定8和9再让让较大的8和末尾元素5进行交换得到数组{4,6,5}
最后就会得到{4,5,6,8,9}
代码实现如下
public static void heapSort(int[] arr){
int temp = 0;
for (int i = arr.length / 2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
for (int j = arr.length - 1; j > 0; j--){
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr,0,j);
}
// System.out.println(Arrays.toString(arr));
}
那么堆排序的核心思想就是上述所说了。这一块我自己学起来也觉得比较难理解。
但是!!!如果难理解,望各位多敲代码。一遍记不住我就敲两边。两遍不行敲三遍、我反正敲了不到20遍,就记住了 也很快!!!
最后还是希望大家能够指认我的错误,谢谢大家。希望能和大家一起共同进步!!!