Heap sort
Introduction
Heap sort is also a sort of selection , the worst and best average time complexity is O(nlogn), which is unstable sort
It is a complete binary tree, the value of each node is greater than or equal to the value of its left and right child nodes ===> large push, note that it does not require the size relationship between the left and right child nodes, otherwise it is a small top heap
Basic idea
1. Construct the sequence to be sorted into a large top heap
At this time, the maximum value of the entire sequence is the root node of the heap item.
Exchange it with the last element, and the end is the maximum value at this time.
Then reconstruct the remaining n-1 elements into a pile, so that the next smallest value of n elements will be obtained. Such repeated execution will result in an ordered sequence.
Diagram
The example in the instructional video is given an array {4,6,8,5,9} using the heap sort algorithm
Then we start from the last non-leaf node (the leaf node naturally does not need to be adjusted, the first non-leaf node arr.length/2-1=5/2-1=1, which is the 6 nodes below), Adjust from left to right and bottom to top .
Then find the second non-leaf node 4, find that 9 elements of 4, 9, 8 are the largest, and 4 and 9 are exchanged
At this time, the exchange caused the structure of the sub-root [4,5,6] to be chaotic, and continue to adjust. In [4,5,6], 6 is the largest, and 4 and 6 are exchanged.
So far, our big push is completed
Step two
Exchange the top element with the last element to make the last element the largest. Then continue to adjust the heap, and
exchange the top element with the last element to get the second largest element. Exchange, rebuild, and exchange are repeated in this way.
9 is not used for sorting anymore, we will treat it as moving out of the array
Then readjust the structure to continue to meet the heap definition
Then swap the top element 8 with the last element 5 to get the second largest element 8.
Subsequent operations repeat the above, and finally get an ordered sequence
Teacher's summary
1. Construct the disordered sequence into a pile, and select the large top pile or the small top pile according to the requirements of ascending and descending order;
2. Exchange the top element with the end element [sink the largest element to the end of the array
3. Re-adjust the structure to meet the definition of the heap, and then continue to exchange the top element of the heap with the current end element, and repeat the adjustment + exchange steps until the entire sequence is in order.
Code
package 树;
import java.util.Arrays;
//堆排序
//2021年1月31日21:26:04
//作者 @王
public class HeapSort {
public static void main(String[] args) {
// TODO Auto-generated method stub
int arr[] ={
4,6,8,5,9};
heapSort(arr);
}
//编写堆排序的方法
public static void heapSort(int[] arr){
int temp = 0;
System.out.println("堆排序");
// //分步完成
// adjustHeap(arr, 1, arr.length);
// System.out.println("第一次调整"+Arrays.toString(arr));
// adjustHeap(arr, 0, arr.length);
// System.out.println("第二次调整"+Arrays.toString(arr));
//将我们的数组变成一个大顶堆
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);
}
}
//将一个数组(二叉树),调整成一个大顶堆或者小顶堆
/**
* 功能:完成将以i对应的非叶子结点的树调整成大顶堆
* 举例 4,6,8,5,9 => i=1 => 得到 4,9,8,5,6
* @param arr
* @param i 表示非叶子节点在数组中的索引
* @param length 表示对多少个元素继续调整,length是在逐渐的减少
*/
public static void adjustHeap(int arr[],int i,int length){
int temp = arr[i];//取出当前元素的值,保存在临时变量
//开始调整
//1. k = i*2+1 k 是i节点的左子节点
for (int k = i * 2 +1; k < length; k = k * 2 +1) {
if(k + 1 < length && arr[k] < arr[k+1]){
//说明左子节点的值小于右子节点的值
k++;//k指向右子节点
}
if(arr[k] > temp){
//如果子节点大于父节点
arr[i] = arr[k];
i = k;//i指向K 继续循环比较
}else{
break;
}
}
//当for循环结束后,我们已经将以i为父节点的树的最大值,放在了最顶上(局部)
arr[i] = temp;
}
}